back to topotato report
topotato coverage report
Current view: top level - zebra - zebra_vty.c (source / functions) Hit Total Coverage
Test: test_ospf6_vlink.py::VirtualLinkBasic Lines: 115 2071 5.6 %
Date: 2023-02-16 02:06:43 Functions: 3 102 2.9 %

          Line data    Source code
       1             : /* Zebra VTY functions
       2             :  * Copyright (C) 2002 Kunihiro Ishiguro
       3             :  *
       4             :  * This file is part of GNU Zebra.
       5             :  *
       6             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * GNU Zebra is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <zebra.h>
      22             : 
      23             : #include "memory.h"
      24             : #include "if.h"
      25             : #include "prefix.h"
      26             : #include "command.h"
      27             : #include "table.h"
      28             : #include "rib.h"
      29             : #include "nexthop.h"
      30             : #include "vrf.h"
      31             : #include "linklist.h"
      32             : #include "mpls.h"
      33             : #include "routemap.h"
      34             : #include "srcdest_table.h"
      35             : #include "vxlan.h"
      36             : #include "termtable.h"
      37             : 
      38             : #include "zebra/zebra_router.h"
      39             : #include "zebra/zserv.h"
      40             : #include "zebra/zebra_vrf.h"
      41             : #include "zebra/zebra_mpls.h"
      42             : #include "zebra/zebra_rnh.h"
      43             : #include "zebra/redistribute.h"
      44             : #include "zebra/zebra_routemap.h"
      45             : #include "lib/json.h"
      46             : #include "lib/route_opaque.h"
      47             : #include "zebra/zebra_vxlan.h"
      48             : #include "zebra/zebra_evpn_mh.h"
      49             : #include "zebra/zebra_vty_clippy.c"
      50             : #include "zebra/zserv.h"
      51             : #include "zebra/router-id.h"
      52             : #include "zebra/ipforward.h"
      53             : #include "zebra/zebra_vxlan_private.h"
      54             : #include "zebra/zebra_pbr.h"
      55             : #include "zebra/zebra_nhg.h"
      56             : #include "zebra/zebra_evpn_mh.h"
      57             : #include "zebra/interface.h"
      58             : #include "northbound_cli.h"
      59             : #include "zebra/zebra_nb.h"
      60             : #include "zebra/kernel_netlink.h"
      61             : #include "zebra/if_netlink.h"
      62             : #include "zebra/table_manager.h"
      63             : #include "zebra/zebra_script.h"
      64             : #include "zebra/rtadv.h"
      65             : #include "zebra/zebra_neigh.h"
      66             : 
      67             : /* context to manage dumps in multiple tables or vrfs */
      68             : struct route_show_ctx {
      69             :         bool multi;       /* dump multiple tables or vrf */
      70             :         bool header_done; /* common header already displayed */
      71             : };
      72             : 
      73             : static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
      74             :                             safi_t safi, bool use_fib, bool use_json,
      75             :                             route_tag_t tag,
      76             :                             const struct prefix *longer_prefix_p,
      77             :                             bool supernets_only, int type,
      78             :                             unsigned short ospf_instance_id, uint32_t tableid,
      79             :                             bool show_ng, struct route_show_ctx *ctx);
      80             : static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
      81             :                                      int mcast, bool use_fib, bool show_ng);
      82             : static void vty_show_ip_route_summary(struct vty *vty,
      83             :                                       struct route_table *table, bool use_json);
      84             : static void vty_show_ip_route_summary_prefix(struct vty *vty,
      85             :                                              struct route_table *table,
      86             :                                              bool use_json);
      87             : /* Helper api to format a nexthop in the 'detailed' output path. */
      88             : static void show_nexthop_detail_helper(struct vty *vty,
      89             :                                        const struct route_entry *re,
      90             :                                        const struct nexthop *nexthop,
      91             :                                        bool is_backup);
      92             : 
      93             : static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table);
      94             : static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop,
      95             :                                    struct route_entry *re, unsigned int num);
      96             : 
      97           0 : DEFUN (ip_multicast_mode,
      98             :        ip_multicast_mode_cmd,
      99             :        "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
     100             :        IP_STR
     101             :        "Multicast options\n"
     102             :        "RPF lookup behavior\n"
     103             :        "Lookup in unicast RIB only\n"
     104             :        "Lookup in multicast RIB only\n"
     105             :        "Try multicast RIB first, fall back to unicast RIB\n"
     106             :        "Lookup both, use entry with lower distance\n"
     107             :        "Lookup both, use entry with longer prefix\n")
     108             : {
     109           0 :         char *mode = argv[3]->text;
     110             : 
     111           0 :         if (strmatch(mode, "urib-only"))
     112           0 :                 multicast_mode_ipv4_set(MCAST_URIB_ONLY);
     113           0 :         else if (strmatch(mode, "mrib-only"))
     114           0 :                 multicast_mode_ipv4_set(MCAST_MRIB_ONLY);
     115           0 :         else if (strmatch(mode, "mrib-then-urib"))
     116           0 :                 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST);
     117           0 :         else if (strmatch(mode, "lower-distance"))
     118           0 :                 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE);
     119           0 :         else if (strmatch(mode, "longer-prefix"))
     120           0 :                 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN);
     121             :         else {
     122           0 :                 vty_out(vty, "Invalid mode specified\n");
     123           0 :                 return CMD_WARNING_CONFIG_FAILED;
     124             :         }
     125             : 
     126             :         return CMD_SUCCESS;
     127             : }
     128             : 
     129           0 : DEFUN (no_ip_multicast_mode,
     130             :        no_ip_multicast_mode_cmd,
     131             :        "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
     132             :        NO_STR
     133             :        IP_STR
     134             :        "Multicast options\n"
     135             :        "RPF lookup behavior\n"
     136             :        "Lookup in unicast RIB only\n"
     137             :        "Lookup in multicast RIB only\n"
     138             :        "Try multicast RIB first, fall back to unicast RIB\n"
     139             :        "Lookup both, use entry with lower distance\n"
     140             :        "Lookup both, use entry with longer prefix\n")
     141             : {
     142           0 :         multicast_mode_ipv4_set(MCAST_NO_CONFIG);
     143           0 :         return CMD_SUCCESS;
     144             : }
     145             : 
     146             : 
     147           0 : DEFUN (show_ip_rpf,
     148             :        show_ip_rpf_cmd,
     149             :        "show ip rpf [json]",
     150             :        SHOW_STR
     151             :        IP_STR
     152             :        "Display RPF information for multicast source\n"
     153             :        JSON_STR)
     154             : {
     155           0 :         bool uj = use_json(argc, argv);
     156           0 :         struct route_show_ctx ctx = {
     157             :                 .multi = false,
     158             :         };
     159             : 
     160           0 :         return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
     161             :                                 false, uj, 0, NULL, false, 0, 0, 0, false,
     162             :                                 &ctx);
     163             : }
     164             : 
     165           0 : DEFUN (show_ip_rpf_addr,
     166             :        show_ip_rpf_addr_cmd,
     167             :        "show ip rpf A.B.C.D",
     168             :        SHOW_STR
     169             :        IP_STR
     170             :        "Display RPF information for multicast source\n"
     171             :        "IP multicast source address (e.g. 10.0.0.0)\n")
     172             : {
     173           0 :         int idx_ipv4 = 3;
     174           0 :         struct in_addr addr;
     175           0 :         struct route_node *rn;
     176           0 :         struct route_entry *re;
     177           0 :         int ret;
     178             : 
     179           0 :         ret = inet_aton(argv[idx_ipv4]->arg, &addr);
     180           0 :         if (ret == 0) {
     181           0 :                 vty_out(vty, "%% Malformed address\n");
     182           0 :                 return CMD_WARNING;
     183             :         }
     184             : 
     185           0 :         re = rib_match_ipv4_multicast(VRF_DEFAULT, addr, &rn);
     186             : 
     187           0 :         if (re)
     188           0 :                 vty_show_ip_route_detail(vty, rn, 1, false, false);
     189             :         else
     190           0 :                 vty_out(vty, "%% No match for RPF lookup\n");
     191             : 
     192             :         return CMD_SUCCESS;
     193             : }
     194             : 
     195           0 : static char re_status_output_char(const struct route_entry *re,
     196             :                                   const struct nexthop *nhop,
     197             :                                   bool is_fib)
     198             : {
     199           0 :         if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
     200           0 :                 bool star_p = false;
     201             : 
     202           0 :                 if (nhop &&
     203           0 :                     !CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_DUPLICATE) &&
     204             :                     !CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE)) {
     205             :                         /* More-specific test for 'fib' output */
     206           0 :                         if (is_fib) {
     207           0 :                                 star_p = !!CHECK_FLAG(nhop->flags,
     208             :                                                       NEXTHOP_FLAG_FIB);
     209             :                         } else
     210             :                                 star_p = true;
     211             :                 }
     212             : 
     213           0 :                 if (zrouter.asic_offloaded &&
     214           0 :                     CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
     215             :                         return 'q';
     216             : 
     217           0 :                 if (zrouter.asic_offloaded
     218           0 :                     && CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED))
     219             :                         return 't';
     220             : 
     221           0 :                 if (zrouter.asic_offloaded
     222           0 :                     && CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED))
     223             :                         return 'o';
     224             : 
     225           0 :                 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OUTOFSYNC))
     226             :                         return 'd';
     227             : 
     228           0 :                 if (star_p)
     229             :                         return '*';
     230             :                 else
     231           0 :                         return ' ';
     232             :         }
     233             : 
     234           0 :         if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED)) {
     235           0 :                 if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
     236             :                         return 'q';
     237             : 
     238           0 :                 return 'r';
     239             :         }
     240             : 
     241           0 :         if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
     242           0 :                 return 'q';
     243             : 
     244             :         return ' ';
     245             : }
     246             : 
     247             : /*
     248             :  * Show backup nexthop info, in the 'detailed' output path
     249             :  */
     250           0 : static void show_nh_backup_helper(struct vty *vty,
     251             :                                   const struct route_entry *re,
     252             :                                   const struct nexthop *nexthop)
     253             : {
     254           0 :         const struct nexthop *start, *backup, *temp;
     255           0 :         int i, idx;
     256             : 
     257             :         /* Double-check that there _is_ a backup */
     258           0 :         if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP) ||
     259           0 :             re->nhe->backup_info == NULL || re->nhe->backup_info->nhe == NULL ||
     260           0 :             re->nhe->backup_info->nhe->nhg.nexthop == NULL)
     261             :                 return;
     262             : 
     263             :         /* Locate the backup nexthop(s) */
     264             :         start = re->nhe->backup_info->nhe->nhg.nexthop;
     265           0 :         for (i = 0; i < nexthop->backup_num; i++) {
     266             :                 /* Format the backup(s) (indented) */
     267             :                 backup = start;
     268           0 :                 for (idx = 0; idx < nexthop->backup_idx[i]; idx++) {
     269           0 :                         backup = backup->next;
     270           0 :                         if (backup == NULL)
     271             :                                 break;
     272             :                 }
     273             : 
     274             :                 /* It's possible for backups to be recursive too,
     275             :                  * so walk the recursive resolution list if present.
     276             :                  */
     277           0 :                 temp = backup;
     278           0 :                 while (backup) {
     279           0 :                         vty_out(vty, "  ");
     280           0 :                         show_nexthop_detail_helper(vty, re, backup,
     281             :                                                    true /*backup*/);
     282           0 :                         vty_out(vty, "\n");
     283             : 
     284           0 :                         if (backup->resolved && temp == backup)
     285             :                                 backup = backup->resolved;
     286             :                         else
     287           0 :                                 backup = nexthop_next(backup);
     288             : 
     289           0 :                         if (backup == temp->next)
     290             :                                 break;
     291             :                 }
     292             :         }
     293             : 
     294             : }
     295             : 
     296             : /*
     297             :  * Helper api to format output for a nexthop, used in the 'detailed'
     298             :  * output path.
     299             :  */
     300           0 : static void show_nexthop_detail_helper(struct vty *vty,
     301             :                                        const struct route_entry *re,
     302             :                                        const struct nexthop *nexthop,
     303             :                                        bool is_backup)
     304             : {
     305           0 :         char addrstr[32];
     306           0 :         char buf[MPLS_LABEL_STRLEN];
     307           0 :         int i;
     308             : 
     309           0 :         if (is_backup)
     310           0 :                 vty_out(vty, "    b%s",
     311           0 :                         nexthop->rparent ? "  " : "");
     312             :         else
     313           0 :                 vty_out(vty, "  %c%s",
     314           0 :                         re_status_output_char(re, nexthop, false),
     315           0 :                         nexthop->rparent ? "  " : "");
     316             : 
     317           0 :         switch (nexthop->type) {
     318           0 :         case NEXTHOP_TYPE_IPV4:
     319             :         case NEXTHOP_TYPE_IPV4_IFINDEX:
     320           0 :                 vty_out(vty, " %pI4",
     321             :                         &nexthop->gate.ipv4);
     322           0 :                 if (nexthop->ifindex)
     323           0 :                         vty_out(vty, ", via %s",
     324             :                                 ifindex2ifname(
     325             :                                         nexthop->ifindex,
     326           0 :                                         nexthop->vrf_id));
     327             :                 break;
     328           0 :         case NEXTHOP_TYPE_IPV6:
     329             :         case NEXTHOP_TYPE_IPV6_IFINDEX:
     330           0 :                 vty_out(vty, " %s",
     331           0 :                         inet_ntop(AF_INET6, &nexthop->gate.ipv6,
     332             :                                   buf, sizeof(buf)));
     333           0 :                 if (nexthop->ifindex)
     334           0 :                         vty_out(vty, ", via %s",
     335             :                                 ifindex2ifname(
     336             :                                         nexthop->ifindex,
     337           0 :                                         nexthop->vrf_id));
     338             :                 break;
     339             : 
     340           0 :         case NEXTHOP_TYPE_IFINDEX:
     341           0 :                 vty_out(vty, " directly connected, %s",
     342           0 :                         ifindex2ifname(nexthop->ifindex,
     343           0 :                                        nexthop->vrf_id));
     344           0 :                 break;
     345           0 :         case NEXTHOP_TYPE_BLACKHOLE:
     346           0 :                 vty_out(vty, " unreachable");
     347           0 :                 switch (nexthop->bh_type) {
     348           0 :                 case BLACKHOLE_REJECT:
     349           0 :                         vty_out(vty, " (ICMP unreachable)");
     350           0 :                         break;
     351           0 :                 case BLACKHOLE_ADMINPROHIB:
     352           0 :                         vty_out(vty,
     353             :                                 " (ICMP admin-prohibited)");
     354           0 :                         break;
     355           0 :                 case BLACKHOLE_NULL:
     356           0 :                         vty_out(vty, " (blackhole)");
     357           0 :                         break;
     358             :                 case BLACKHOLE_UNSPEC:
     359             :                         break;
     360             :                 }
     361             :                 break;
     362             :         }
     363             : 
     364           0 :         if (re->vrf_id != nexthop->vrf_id) {
     365           0 :                 struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
     366             : 
     367           0 :                 vty_out(vty, "(vrf %s)", VRF_LOGNAME(vrf));
     368             :         }
     369             : 
     370           0 :         if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
     371           0 :                 vty_out(vty, " (duplicate nexthop removed)");
     372             : 
     373           0 :         if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
     374           0 :                 vty_out(vty, " inactive");
     375             : 
     376           0 :         if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
     377           0 :                 vty_out(vty, " onlink");
     378             : 
     379           0 :         if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN))
     380           0 :                 vty_out(vty, " linkdown");
     381             : 
     382           0 :         if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
     383           0 :                 vty_out(vty, " (recursive)");
     384             : 
     385             :         /* Source specified? */
     386           0 :         switch (nexthop->type) {
     387           0 :         case NEXTHOP_TYPE_IPV4:
     388             :         case NEXTHOP_TYPE_IPV4_IFINDEX:
     389           0 :                 if (nexthop->src.ipv4.s_addr) {
     390           0 :                         if (inet_ntop(AF_INET, &nexthop->src.ipv4,
     391             :                                       addrstr, sizeof(addrstr)))
     392           0 :                                 vty_out(vty, ", src %s",
     393             :                                         addrstr);
     394             :                 }
     395             :                 break;
     396             : 
     397           0 :         case NEXTHOP_TYPE_IPV6:
     398             :         case NEXTHOP_TYPE_IPV6_IFINDEX:
     399           0 :                 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
     400             :                                     &in6addr_any)) {
     401           0 :                         if (inet_ntop(AF_INET6, &nexthop->src.ipv6,
     402             :                                       addrstr, sizeof(addrstr)))
     403           0 :                                 vty_out(vty, ", src %s",
     404             :                                         addrstr);
     405             :                 }
     406             :                 break;
     407             : 
     408             :         case NEXTHOP_TYPE_IFINDEX:
     409             :         case NEXTHOP_TYPE_BLACKHOLE:
     410             :                 break;
     411             :         }
     412             : 
     413           0 :         if (re->nexthop_mtu)
     414           0 :                 vty_out(vty, ", mtu %u", re->nexthop_mtu);
     415             : 
     416             :         /* Label information */
     417           0 :         if (nexthop->nh_label && nexthop->nh_label->num_labels) {
     418           0 :                 vty_out(vty, ", label %s",
     419             :                         mpls_label2str(nexthop->nh_label->num_labels,
     420           0 :                                        nexthop->nh_label->label, buf,
     421             :                                        sizeof(buf), 1 /*pretty*/));
     422             :         }
     423             : 
     424           0 :         if (nexthop->weight)
     425           0 :                 vty_out(vty, ", weight %u", nexthop->weight);
     426             : 
     427           0 :         if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
     428           0 :                 vty_out(vty, ", backup %d", nexthop->backup_idx[0]);
     429             : 
     430           0 :                 for (i = 1; i < nexthop->backup_num; i++)
     431           0 :                         vty_out(vty, ",%d", nexthop->backup_idx[i]);
     432             :         }
     433           0 : }
     434             : 
     435           0 : static void zebra_show_ip_route_opaque(struct vty *vty, struct route_entry *re,
     436             :                                        struct json_object *json)
     437             : {
     438           0 :         struct bgp_zebra_opaque bzo = {};
     439           0 :         struct ospf_zebra_opaque ozo = {};
     440             : 
     441           0 :         if (!re->opaque)
     442           0 :                 return;
     443             : 
     444           0 :         switch (re->type) {
     445           0 :         case ZEBRA_ROUTE_SHARP:
     446           0 :                 if (json)
     447           0 :                         json_object_string_add(json, "opaque",
     448           0 :                                                (char *)re->opaque->data);
     449             :                 else
     450           0 :                         vty_out(vty, "    Opaque Data: %s",
     451           0 :                                 (char *)re->opaque->data);
     452             :                 break;
     453             : 
     454           0 :         case ZEBRA_ROUTE_BGP:
     455           0 :                 memcpy(&bzo, re->opaque->data, re->opaque->length);
     456             : 
     457           0 :                 if (json) {
     458           0 :                         json_object_string_add(json, "asPath", bzo.aspath);
     459           0 :                         json_object_string_add(json, "communities",
     460             :                                                bzo.community);
     461           0 :                         json_object_string_add(json, "largeCommunities",
     462             :                                                bzo.lcommunity);
     463           0 :                         json_object_string_add(json, "selectionReason",
     464             :                                                bzo.selection_reason);
     465             :                 } else {
     466           0 :                         vty_out(vty, "    AS-Path          : %s\n", bzo.aspath);
     467             : 
     468           0 :                         if (bzo.community[0] != '\0')
     469           0 :                                 vty_out(vty, "    Communities      : %s\n",
     470             :                                         bzo.community);
     471             : 
     472           0 :                         if (bzo.lcommunity[0] != '\0')
     473           0 :                                 vty_out(vty, "    Large-Communities: %s\n",
     474             :                                         bzo.lcommunity);
     475             : 
     476           0 :                         vty_out(vty, "    Selection reason : %s\n",
     477             :                                 bzo.selection_reason);
     478             :                 }
     479             :                 break;
     480           0 :         case ZEBRA_ROUTE_OSPF:
     481             :         case ZEBRA_ROUTE_OSPF6:
     482           0 :                 memcpy(&ozo, re->opaque->data, re->opaque->length);
     483             : 
     484           0 :                 if (json) {
     485           0 :                         json_object_string_add(json, "ospfPathType",
     486             :                                                ozo.path_type);
     487           0 :                         if (ozo.area_id[0] != '\0')
     488           0 :                                 json_object_string_add(json, "ospfAreaId",
     489             :                                                        ozo.area_id);
     490           0 :                         if (ozo.tag[0] != '\0')
     491           0 :                                 json_object_string_add(json, "ospfTag",
     492             :                                                        ozo.tag);
     493             :                 } else {
     494           0 :                         vty_out(vty, "    OSPF path type        : %s\n",
     495             :                                 ozo.path_type);
     496           0 :                         if (ozo.area_id[0] != '\0')
     497           0 :                                 vty_out(vty, "    OSPF area ID          : %s\n",
     498             :                                         ozo.area_id);
     499           0 :                         if (ozo.tag[0] != '\0')
     500           0 :                                 vty_out(vty, "    OSPF tag              : %s\n",
     501             :                                         ozo.tag);
     502             :                 }
     503             :                 break;
     504             :         default:
     505             :                 break;
     506             :         }
     507             : }
     508             : 
     509           0 : static void uptime2str(time_t uptime, char *buf, size_t bufsize)
     510             : {
     511           0 :         time_t cur;
     512             : 
     513           0 :         cur = monotime(NULL);
     514           0 :         cur -= uptime;
     515             : 
     516           0 :         frrtime_to_interval(cur, buf, bufsize);
     517           0 : }
     518             : 
     519             : /* New RIB.  Detailed information for IPv4 route. */
     520           0 : static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
     521             :                                      int mcast, bool use_fib, bool show_ng)
     522             : {
     523           0 :         struct route_entry *re;
     524           0 :         struct nexthop *nexthop;
     525           0 :         char buf[SRCDEST2STR_BUFFER];
     526           0 :         struct zebra_vrf *zvrf;
     527           0 :         rib_dest_t *dest;
     528             : 
     529           0 :         dest = rib_dest_from_rnode(rn);
     530             : 
     531           0 :         RNODE_FOREACH_RE (rn, re) {
     532             :                 /*
     533             :                  * If re not selected for forwarding, skip re
     534             :                  * for "show ip/ipv6 fib <prefix>"
     535             :                  */
     536           0 :                 if (use_fib && re != dest->selected_fib)
     537           0 :                         continue;
     538             : 
     539           0 :                 const char *mcast_info = "";
     540           0 :                 if (mcast) {
     541           0 :                         struct rib_table_info *info =
     542           0 :                                 srcdest_rnode_table_info(rn);
     543           0 :                         mcast_info = (info->safi == SAFI_MULTICAST)
     544             :                                              ? " using Multicast RIB"
     545           0 :                                              : " using Unicast RIB";
     546             :                 }
     547             : 
     548           0 :                 vty_out(vty, "Routing entry for %s%s\n",
     549             :                         srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info);
     550           0 :                 vty_out(vty, "  Known via \"%s", zebra_route_string(re->type));
     551           0 :                 if (re->instance)
     552           0 :                         vty_out(vty, "[%d]", re->instance);
     553           0 :                 vty_out(vty, "\"");
     554           0 :                 vty_out(vty, ", distance %u, metric %u", re->distance,
     555             :                         re->metric);
     556           0 :                 if (re->tag) {
     557           0 :                         vty_out(vty, ", tag %u", re->tag);
     558             : #if defined(SUPPORT_REALMS)
     559             :                         if (re->tag > 0 && re->tag <= 255)
     560             :                                 vty_out(vty, "(realm)");
     561             : #endif
     562             :                 }
     563           0 :                 if (re->mtu)
     564           0 :                         vty_out(vty, ", mtu %u", re->mtu);
     565           0 :                 if (re->vrf_id != VRF_DEFAULT) {
     566           0 :                         zvrf = vrf_info_lookup(re->vrf_id);
     567           0 :                         vty_out(vty, ", vrf %s", zvrf_name(zvrf));
     568             :                 }
     569           0 :                 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
     570           0 :                         vty_out(vty, ", best");
     571           0 :                 vty_out(vty, "\n");
     572             : 
     573           0 :                 uptime2str(re->uptime, buf, sizeof(buf));
     574             : 
     575           0 :                 vty_out(vty, "  Last update %s ago\n", buf);
     576             : 
     577           0 :                 if (show_ng) {
     578           0 :                         vty_out(vty, "  Nexthop Group ID: %u\n", re->nhe_id);
     579           0 :                         if (re->nhe_installed_id != 0
     580           0 :                             && re->nhe_id != re->nhe_installed_id)
     581           0 :                                 vty_out(vty,
     582             :                                         "  Installed Nexthop Group ID: %u\n",
     583             :                                         re->nhe_installed_id);
     584             :                 }
     585             : 
     586           0 :                 for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
     587             :                         /* Use helper to format each nexthop */
     588           0 :                         show_nexthop_detail_helper(vty, re, nexthop,
     589             :                                                    false /*not backup*/);
     590           0 :                         vty_out(vty, "\n");
     591             : 
     592             :                         /* Include backup(s), if present */
     593           0 :                         if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP))
     594           0 :                                 show_nh_backup_helper(vty, re, nexthop);
     595             :                 }
     596           0 :                 zebra_show_ip_route_opaque(vty, re, NULL);
     597             : 
     598           0 :                 vty_out(vty, "\n");
     599             :         }
     600           0 : }
     601             : 
     602           0 : static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
     603             :                               struct route_entry *re, json_object *json,
     604             :                               bool is_fib, bool show_ng)
     605             : {
     606           0 :         const struct nexthop *nexthop;
     607           0 :         int len = 0;
     608           0 :         char buf[SRCDEST2STR_BUFFER];
     609           0 :         json_object *json_nexthops = NULL;
     610           0 :         json_object *json_nexthop = NULL;
     611           0 :         json_object *json_route = NULL;
     612           0 :         const rib_dest_t *dest = rib_dest_from_rnode(rn);
     613           0 :         const struct nexthop_group *nhg;
     614           0 :         char up_str[MONOTIME_STRLEN];
     615           0 :         bool first_p = true;
     616           0 :         bool nhg_from_backup = false;
     617             : 
     618           0 :         uptime2str(re->uptime, up_str, sizeof(up_str));
     619             : 
     620             :         /* If showing fib information, use the fib view of the
     621             :          * nexthops.
     622             :          */
     623           0 :         if (is_fib)
     624           0 :                 nhg = rib_get_fib_nhg(re);
     625             :         else
     626           0 :                 nhg = &(re->nhe->nhg);
     627             : 
     628           0 :         if (json) {
     629           0 :                 json_route = json_object_new_object();
     630           0 :                 json_nexthops = json_object_new_array();
     631             : 
     632           0 :                 json_object_string_add(json_route, "prefix",
     633             :                                        srcdest_rnode2str(rn, buf, sizeof(buf)));
     634           0 :                 json_object_int_add(json_route, "prefixLen", rn->p.prefixlen);
     635           0 :                 json_object_string_add(json_route, "protocol",
     636           0 :                                        zebra_route_string(re->type));
     637             : 
     638           0 :                 if (re->instance)
     639           0 :                         json_object_int_add(json_route, "instance",
     640             :                                             re->instance);
     641             : 
     642           0 :                 json_object_int_add(json_route, "vrfId", re->vrf_id);
     643           0 :                 json_object_string_add(json_route, "vrfName",
     644             :                                        vrf_id_to_name(re->vrf_id));
     645             : 
     646           0 :                 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
     647           0 :                         json_object_boolean_true_add(json_route, "selected");
     648             : 
     649           0 :                 if (dest->selected_fib == re)
     650           0 :                         json_object_boolean_true_add(json_route,
     651             :                                                      "destSelected");
     652             : 
     653           0 :                 json_object_int_add(json_route, "distance",
     654           0 :                                     re->distance);
     655           0 :                 json_object_int_add(json_route, "metric", re->metric);
     656             : 
     657           0 :                 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
     658           0 :                         json_object_boolean_true_add(json_route, "installed");
     659             : 
     660           0 :                 if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED))
     661           0 :                         json_object_boolean_true_add(json_route, "failed");
     662             : 
     663           0 :                 if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
     664           0 :                         json_object_boolean_true_add(json_route, "queued");
     665             : 
     666           0 :                 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED))
     667           0 :                         json_object_boolean_true_add(json_route, "trapped");
     668             : 
     669           0 :                 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED))
     670           0 :                         json_object_boolean_true_add(json_route, "offloaded");
     671             : 
     672           0 :                 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED))
     673           0 :                         json_object_boolean_false_add(json_route, "offloaded");
     674             : 
     675           0 :                 if (re->tag)
     676           0 :                         json_object_int_add(json_route, "tag", re->tag);
     677             : 
     678           0 :                 if (re->table)
     679           0 :                         json_object_int_add(json_route, "table", re->table);
     680             : 
     681           0 :                 json_object_int_add(json_route, "internalStatus",
     682           0 :                                     re->status);
     683           0 :                 json_object_int_add(json_route, "internalFlags",
     684           0 :                                     re->flags);
     685           0 :                 json_object_int_add(json_route, "internalNextHopNum",
     686           0 :                                     nexthop_group_nexthop_num(&(re->nhe->nhg)));
     687           0 :                 json_object_int_add(json_route, "internalNextHopActiveNum",
     688           0 :                                     nexthop_group_active_nexthop_num(
     689           0 :                                             &(re->nhe->nhg)));
     690           0 :                 json_object_int_add(json_route, "nexthopGroupId", re->nhe_id);
     691             : 
     692           0 :                 if (re->nhe_installed_id != 0)
     693           0 :                         json_object_int_add(json_route,
     694             :                                             "installedNexthopGroupId",
     695             :                                             re->nhe_installed_id);
     696             : 
     697           0 :                 json_object_string_add(json_route, "uptime", up_str);
     698             : 
     699           0 :                 for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
     700           0 :                         json_nexthop = json_object_new_object();
     701           0 :                         show_nexthop_json_helper(json_nexthop,
     702             :                                                  nexthop, re);
     703             : 
     704           0 :                         json_object_array_add(json_nexthops,
     705             :                                               json_nexthop);
     706             :                 }
     707             : 
     708           0 :                 json_object_object_add(json_route, "nexthops", json_nexthops);
     709             : 
     710             :                 /* If there are backup nexthops, include them */
     711           0 :                 if (is_fib)
     712           0 :                         nhg = rib_get_fib_backup_nhg(re);
     713             :                 else
     714           0 :                         nhg = zebra_nhg_get_backup_nhg(re->nhe);
     715             : 
     716           0 :                 if (nhg && nhg->nexthop) {
     717           0 :                         json_nexthops = json_object_new_array();
     718             : 
     719           0 :                         for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
     720           0 :                                 json_nexthop = json_object_new_object();
     721             : 
     722           0 :                                 show_nexthop_json_helper(json_nexthop,
     723             :                                                          nexthop, re);
     724           0 :                                 json_object_array_add(json_nexthops,
     725             :                                                       json_nexthop);
     726             :                         }
     727             : 
     728           0 :                         json_object_object_add(json_route, "backupNexthops",
     729             :                                                json_nexthops);
     730             :                 }
     731           0 :                 zebra_show_ip_route_opaque(NULL, re, json_route);
     732             : 
     733           0 :                 json_object_array_add(json, json_route);
     734           0 :                 return;
     735             :         }
     736             : 
     737             :         /* Prefix information, and first nexthop. If we're showing 'fib',
     738             :          * and there are no installed primary nexthops, see if there are any
     739             :          * backup nexthops and start with those.
     740             :          */
     741           0 :         if (is_fib && nhg->nexthop == NULL) {
     742           0 :                 nhg = rib_get_fib_backup_nhg(re);
     743           0 :                 nhg_from_backup = true;
     744             :         }
     745             : 
     746           0 :         len = vty_out(vty, "%c", zebra_route_char(re->type));
     747           0 :         if (re->instance)
     748           0 :                 len += vty_out(vty, "[%d]", re->instance);
     749           0 :         if (nhg_from_backup && nhg->nexthop) {
     750           0 :                 len += vty_out(
     751             :                         vty, "%cb%c %s",
     752           0 :                         CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED) ? '>' : ' ',
     753           0 :                         re_status_output_char(re, nhg->nexthop, is_fib),
     754           0 :                         srcdest_rnode2str(rn, buf, sizeof(buf)));
     755             :         } else {
     756           0 :                 len += vty_out(
     757             :                         vty, "%c%c %s",
     758           0 :                         CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED) ? '>' : ' ',
     759           0 :                         re_status_output_char(re, nhg->nexthop, is_fib),
     760             :                         srcdest_rnode2str(rn, buf, sizeof(buf)));
     761             :         }
     762             : 
     763             :         /* Distance and metric display. */
     764           0 :         if (((re->type == ZEBRA_ROUTE_CONNECT) &&
     765           0 :              (re->distance || re->metric)) ||
     766             :             (re->type != ZEBRA_ROUTE_CONNECT))
     767           0 :                 len += vty_out(vty, " [%u/%u]", re->distance,
     768             :                                re->metric);
     769             : 
     770           0 :         if (show_ng)
     771           0 :                 len += vty_out(vty, " (%u)", re->nhe_id);
     772             : 
     773             :         /* Nexthop information. */
     774           0 :         for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
     775           0 :                 if (first_p) {
     776             :                         first_p = false;
     777           0 :                 } else if (nhg_from_backup) {
     778           0 :                         vty_out(vty, "  b%c%*c",
     779           0 :                                 re_status_output_char(re, nexthop, is_fib),
     780           0 :                                 len - 3 + (2 * nexthop_level(nexthop)), ' ');
     781             :                 } else {
     782           0 :                         vty_out(vty, "  %c%*c",
     783           0 :                                 re_status_output_char(re, nexthop, is_fib),
     784           0 :                                 len - 3 + (2 * nexthop_level(nexthop)), ' ');
     785             :                 }
     786             : 
     787           0 :                 show_route_nexthop_helper(vty, re, nexthop);
     788           0 :                 vty_out(vty, ", %s\n", up_str);
     789             :         }
     790             : 
     791             :         /* If we only had backup nexthops, we're done */
     792           0 :         if (nhg_from_backup)
     793             :                 return;
     794             : 
     795             :         /* Check for backup nexthop info if present */
     796           0 :         if (is_fib)
     797           0 :                 nhg = rib_get_fib_backup_nhg(re);
     798             :         else
     799           0 :                 nhg = zebra_nhg_get_backup_nhg(re->nhe);
     800             : 
     801           0 :         if (nhg == NULL)
     802             :                 return;
     803             : 
     804             :         /* Print backup info */
     805           0 :         for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
     806           0 :                 bool star_p = false;
     807             : 
     808           0 :                 if (is_fib)
     809           0 :                         star_p = CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
     810             : 
     811             :                 /* TODO -- it'd be nice to be able to include
     812             :                  * the entire list of backups, *and* include the
     813             :                  * real installation state.
     814             :                  */
     815           0 :                 vty_out(vty, "  b%c %*c",
     816             :                         (star_p ? '*' : ' '),
     817           0 :                         len - 3 + (2 * nexthop_level(nexthop)), ' ');
     818           0 :                 show_route_nexthop_helper(vty, re, nexthop);
     819           0 :                 vty_out(vty, "\n");
     820             :         }
     821             : 
     822             : }
     823             : 
     824           0 : static void vty_show_ip_route_detail_json(struct vty *vty,
     825             :                                           struct route_node *rn, bool use_fib)
     826             : {
     827           0 :         json_object *json = NULL;
     828           0 :         json_object *json_prefix = NULL;
     829           0 :         struct route_entry *re;
     830           0 :         char buf[BUFSIZ];
     831           0 :         rib_dest_t *dest;
     832             : 
     833           0 :         dest = rib_dest_from_rnode(rn);
     834             : 
     835           0 :         json = json_object_new_object();
     836           0 :         json_prefix = json_object_new_array();
     837             : 
     838           0 :         RNODE_FOREACH_RE (rn, re) {
     839             :                 /*
     840             :                  * If re not selected for forwarding, skip re
     841             :                  * for "show ip/ipv6 fib <prefix> json"
     842             :                  */
     843           0 :                 if (use_fib && re != dest->selected_fib)
     844           0 :                         continue;
     845           0 :                 vty_show_ip_route(vty, rn, re, json_prefix, use_fib, false);
     846             :         }
     847             : 
     848           0 :         prefix2str(&rn->p, buf, sizeof(buf));
     849           0 :         json_object_object_add(json, buf, json_prefix);
     850           0 :         vty_json(vty, json);
     851           0 : }
     852             : 
     853           0 : static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
     854             :                                  struct route_table *table, afi_t afi,
     855             :                                  bool use_fib, route_tag_t tag,
     856             :                                  const struct prefix *longer_prefix_p,
     857             :                                  bool supernets_only, int type,
     858             :                                  unsigned short ospf_instance_id, bool use_json,
     859             :                                  uint32_t tableid, bool show_ng,
     860             :                                  struct route_show_ctx *ctx)
     861             : {
     862           0 :         struct route_node *rn;
     863           0 :         struct route_entry *re;
     864           0 :         int first = 1;
     865           0 :         rib_dest_t *dest;
     866           0 :         json_object *json = NULL;
     867           0 :         json_object *json_prefix = NULL;
     868           0 :         uint32_t addr;
     869           0 :         char buf[BUFSIZ];
     870             : 
     871             :         /*
     872             :          * ctx->multi indicates if we are dumping multiple tables or vrfs.
     873             :          * if set:
     874             :          *   => display the common header at most once
     875             :          *   => add newline at each call except first
     876             :          *   => always display the VRF and table
     877             :          * else:
     878             :          *   => display the common header if at least one entry is found
     879             :          *   => display the VRF and table if specific
     880             :          */
     881             : 
     882           0 :         if (use_json)
     883           0 :                 json = json_object_new_object();
     884             : 
     885             :         /* Show all routes. */
     886           0 :         for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
     887           0 :                 dest = rib_dest_from_rnode(rn);
     888             : 
     889           0 :                 RNODE_FOREACH_RE (rn, re) {
     890           0 :                         if (use_fib && re != dest->selected_fib)
     891           0 :                                 continue;
     892             : 
     893           0 :                         if (tag && re->tag != tag)
     894           0 :                                 continue;
     895             : 
     896           0 :                         if (longer_prefix_p
     897           0 :                             && !prefix_match(longer_prefix_p, &rn->p))
     898           0 :                                 continue;
     899             : 
     900             :                         /* This can only be true when the afi is IPv4 */
     901           0 :                         if (supernets_only) {
     902           0 :                                 addr = ntohl(rn->p.u.prefix4.s_addr);
     903             : 
     904           0 :                                 if (IN_CLASSC(addr) && rn->p.prefixlen >= 24)
     905           0 :                                         continue;
     906             : 
     907           0 :                                 if (IN_CLASSB(addr) && rn->p.prefixlen >= 16)
     908           0 :                                         continue;
     909             : 
     910           0 :                                 if (IN_CLASSA(addr) && rn->p.prefixlen >= 8)
     911           0 :                                         continue;
     912             :                         }
     913             : 
     914           0 :                         if (type && re->type != type)
     915           0 :                                 continue;
     916             : 
     917           0 :                         if (ospf_instance_id
     918           0 :                             && (re->type != ZEBRA_ROUTE_OSPF
     919           0 :                                 || re->instance != ospf_instance_id))
     920           0 :                                 continue;
     921             : 
     922           0 :                         if (use_json) {
     923           0 :                                 if (!json_prefix)
     924           0 :                                         json_prefix = json_object_new_array();
     925           0 :                         } else if (first) {
     926           0 :                                 if (!ctx->header_done) {
     927           0 :                                         if (afi == AFI_IP)
     928           0 :                                                 vty_out(vty,
     929             :                                                         SHOW_ROUTE_V4_HEADER);
     930             :                                         else
     931           0 :                                                 vty_out(vty,
     932             :                                                         SHOW_ROUTE_V6_HEADER);
     933             :                                 }
     934           0 :                                 if (ctx->multi && ctx->header_done)
     935           0 :                                         vty_out(vty, "\n");
     936           0 :                                 if (ctx->multi || zvrf_id(zvrf) != VRF_DEFAULT
     937           0 :                                     || tableid) {
     938           0 :                                         if (!tableid)
     939           0 :                                                 vty_out(vty, "VRF %s:\n",
     940             :                                                         zvrf_name(zvrf));
     941             :                                         else
     942           0 :                                                 vty_out(vty,
     943             :                                                         "VRF %s table %u:\n",
     944             :                                                         zvrf_name(zvrf),
     945             :                                                         tableid);
     946             :                                 }
     947           0 :                                 ctx->header_done = true;
     948           0 :                                 first = 0;
     949             :                         }
     950             : 
     951           0 :                         vty_show_ip_route(vty, rn, re, json_prefix, use_fib,
     952             :                                           show_ng);
     953             :                 }
     954             : 
     955           0 :                 if (json_prefix) {
     956           0 :                         prefix2str(&rn->p, buf, sizeof(buf));
     957           0 :                         json_object_object_add(json, buf, json_prefix);
     958           0 :                         json_prefix = NULL;
     959             :                 }
     960             :         }
     961             : 
     962           0 :         if (use_json)
     963           0 :                 vty_json(vty, json);
     964           0 : }
     965             : 
     966           0 : static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf,
     967             :                                  afi_t afi, bool use_fib, bool use_json,
     968             :                                  route_tag_t tag,
     969             :                                  const struct prefix *longer_prefix_p,
     970             :                                  bool supernets_only, int type,
     971             :                                  unsigned short ospf_instance_id, bool show_ng,
     972             :                                  struct route_show_ctx *ctx)
     973             : {
     974           0 :         struct zebra_router_table *zrt;
     975           0 :         struct rib_table_info *info;
     976             : 
     977           0 :         RB_FOREACH (zrt, zebra_router_table_head,
     978             :                     &zrouter.tables) {
     979           0 :                 info = route_table_get_info(zrt->table);
     980             : 
     981           0 :                 if (zvrf != info->zvrf)
     982           0 :                         continue;
     983           0 :                 if (zrt->afi != afi ||
     984           0 :                     zrt->safi != SAFI_UNICAST)
     985           0 :                         continue;
     986             : 
     987           0 :                 do_show_ip_route(vty, zvrf_name(zvrf), afi, SAFI_UNICAST,
     988             :                                  use_fib, use_json, tag, longer_prefix_p,
     989             :                                  supernets_only, type, ospf_instance_id,
     990             :                                  zrt->tableid, show_ng, ctx);
     991             :         }
     992           0 : }
     993             : 
     994           0 : static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
     995             :                             safi_t safi, bool use_fib, bool use_json,
     996             :                             route_tag_t tag,
     997             :                             const struct prefix *longer_prefix_p,
     998             :                             bool supernets_only, int type,
     999             :                             unsigned short ospf_instance_id, uint32_t tableid,
    1000             :                             bool show_ng, struct route_show_ctx *ctx)
    1001             : {
    1002           0 :         struct route_table *table;
    1003           0 :         struct zebra_vrf *zvrf = NULL;
    1004             : 
    1005           0 :         if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
    1006           0 :                 if (use_json)
    1007           0 :                         vty_out(vty, "{}\n");
    1008             :                 else
    1009           0 :                         vty_out(vty, "vrf %s not defined\n", vrf_name);
    1010           0 :                 return CMD_SUCCESS;
    1011             :         }
    1012             : 
    1013           0 :         if (zvrf_id(zvrf) == VRF_UNKNOWN) {
    1014           0 :                 if (use_json)
    1015           0 :                         vty_out(vty, "{}\n");
    1016             :                 else
    1017           0 :                         vty_out(vty, "vrf %s inactive\n", vrf_name);
    1018           0 :                 return CMD_SUCCESS;
    1019             :         }
    1020             : 
    1021           0 :         if (tableid)
    1022           0 :                 table = zebra_router_find_table(zvrf, tableid, afi, SAFI_UNICAST);
    1023             :         else
    1024           0 :                 table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
    1025           0 :         if (!table) {
    1026           0 :                 if (use_json)
    1027           0 :                         vty_out(vty, "{}\n");
    1028           0 :                 return CMD_SUCCESS;
    1029             :         }
    1030             : 
    1031           0 :         do_show_route_helper(vty, zvrf, table, afi, use_fib, tag,
    1032             :                              longer_prefix_p, supernets_only, type,
    1033             :                              ospf_instance_id, use_json, tableid, show_ng, ctx);
    1034             : 
    1035           0 :         return CMD_SUCCESS;
    1036             : }
    1037             : 
    1038           0 : DEFPY (show_ip_nht,
    1039             :        show_ip_nht_cmd,
    1040             :        "show <ip$ipv4|ipv6$ipv6> <nht|import-check>$type [<A.B.C.D|X:X::X:X>$addr|vrf NAME$vrf_name [<A.B.C.D|X:X::X:X>$addr]|vrf all$vrf_all] [mrib$mrib] [json]",
    1041             :        SHOW_STR
    1042             :        IP_STR
    1043             :        IP6_STR
    1044             :        "IP nexthop tracking table\n"
    1045             :        "IP import check tracking table\n"
    1046             :        "IPv4 Address\n"
    1047             :        "IPv6 Address\n"
    1048             :        VRF_CMD_HELP_STR
    1049             :        "IPv4 Address\n"
    1050             :        "IPv6 Address\n"
    1051             :        VRF_ALL_CMD_HELP_STR
    1052             :        "Show Multicast (MRIB) NHT state\n"
    1053             :        JSON_STR)
    1054             : {
    1055           0 :         afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
    1056           0 :         vrf_id_t vrf_id = VRF_DEFAULT;
    1057           0 :         struct prefix prefix, *p = NULL;
    1058           0 :         safi_t safi = mrib ? SAFI_MULTICAST : SAFI_UNICAST;
    1059           0 :         bool uj = use_json(argc, argv);
    1060           0 :         json_object *json = NULL;
    1061           0 :         json_object *json_vrf = NULL;
    1062           0 :         json_object *json_nexthop = NULL;
    1063             : 
    1064           0 :         if (uj)
    1065           0 :                 json = json_object_new_object();
    1066             : 
    1067           0 :         if (vrf_all) {
    1068           0 :                 struct vrf *vrf;
    1069           0 :                 struct zebra_vrf *zvrf;
    1070             : 
    1071           0 :                 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    1072           0 :                         if ((zvrf = vrf->info) != NULL) {
    1073           0 :                                 if (uj) {
    1074           0 :                                         json_vrf = json_object_new_object();
    1075           0 :                                         json_nexthop = json_object_new_object();
    1076           0 :                                         json_object_object_add(json,
    1077             :                                                                zvrf_name(zvrf),
    1078             :                                                                json_vrf);
    1079           0 :                                         json_object_object_add(json_vrf,
    1080             :                                                                (afi == AFI_IP)
    1081             :                                                                        ? "ipv4"
    1082             :                                                                        : "ipv6",
    1083             :                                                                json_nexthop);
    1084             :                                 } else {
    1085           0 :                                         vty_out(vty, "\nVRF %s:\n",
    1086             :                                                 zvrf_name(zvrf));
    1087             :                                 }
    1088           0 :                                 zebra_print_rnh_table(zvrf_id(zvrf), afi, safi,
    1089             :                                                       vty, NULL, json_nexthop);
    1090             :                         }
    1091             :                 }
    1092             : 
    1093           0 :                 if (uj)
    1094           0 :                         vty_json(vty, json);
    1095             : 
    1096           0 :                 return CMD_SUCCESS;
    1097             :         }
    1098           0 :         if (vrf_name)
    1099           0 :                 VRF_GET_ID(vrf_id, vrf_name, false);
    1100             : 
    1101           0 :         memset(&prefix, 0, sizeof(prefix));
    1102           0 :         if (addr) {
    1103           0 :                 p = sockunion2hostprefix(addr, &prefix);
    1104           0 :                 if (!p) {
    1105           0 :                         if (uj)
    1106           0 :                                 json_object_free(json);
    1107           0 :                         return CMD_WARNING;
    1108             :                 }
    1109             :         }
    1110             : 
    1111           0 :         if (uj) {
    1112           0 :                 json_vrf = json_object_new_object();
    1113           0 :                 json_nexthop = json_object_new_object();
    1114           0 :                 if (vrf_name)
    1115           0 :                         json_object_object_add(json, vrf_name, json_vrf);
    1116             :                 else
    1117           0 :                         json_object_object_add(json, "default", json_vrf);
    1118             : 
    1119           0 :                 json_object_object_add(json_vrf,
    1120             :                                        (afi == AFI_IP) ? "ipv4" : "ipv6",
    1121             :                                        json_nexthop);
    1122             :         }
    1123             : 
    1124           0 :         zebra_print_rnh_table(vrf_id, afi, safi, vty, p, json_nexthop);
    1125             : 
    1126           0 :         if (uj)
    1127           0 :                 vty_json(vty, json);
    1128             : 
    1129             :         return CMD_SUCCESS;
    1130             : }
    1131             : 
    1132           0 : DEFUN (ip_nht_default_route,
    1133             :        ip_nht_default_route_cmd,
    1134             :        "ip nht resolve-via-default",
    1135             :        IP_STR
    1136             :        "Filter Next Hop tracking route resolution\n"
    1137             :        "Resolve via default route\n")
    1138             : {
    1139           0 :         ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
    1140             : 
    1141           0 :         if (!zvrf)
    1142             :                 return CMD_WARNING;
    1143             : 
    1144           0 :         if (zvrf->zebra_rnh_ip_default_route)
    1145             :                 return CMD_SUCCESS;
    1146             : 
    1147           0 :         zvrf->zebra_rnh_ip_default_route = true;
    1148             : 
    1149           0 :         zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST);
    1150           0 :         return CMD_SUCCESS;
    1151             : }
    1152             : 
    1153           0 : static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe,
    1154             :                                    json_object *json_nhe_hdr)
    1155             : {
    1156           0 :         struct nexthop *nexthop = NULL;
    1157           0 :         struct nhg_connected *rb_node_dep = NULL;
    1158           0 :         struct nexthop_group *backup_nhg;
    1159           0 :         char up_str[MONOTIME_STRLEN];
    1160           0 :         char time_left[MONOTIME_STRLEN];
    1161           0 :         json_object *json_dependants = NULL;
    1162           0 :         json_object *json_depends = NULL;
    1163           0 :         json_object *json_nexthop_array = NULL;
    1164           0 :         json_object *json_nexthops = NULL;
    1165           0 :         json_object *json = NULL;
    1166           0 :         json_object *json_backup_nexthop_array = NULL;
    1167           0 :         json_object *json_backup_nexthops = NULL;
    1168             : 
    1169             : 
    1170           0 :         uptime2str(nhe->uptime, up_str, sizeof(up_str));
    1171             : 
    1172           0 :         if (json_nhe_hdr)
    1173           0 :                 json = json_object_new_object();
    1174             : 
    1175           0 :         if (json) {
    1176           0 :                 json_object_string_add(json, "type",
    1177           0 :                                        zebra_route_string(nhe->type));
    1178           0 :                 json_object_int_add(json, "refCount", nhe->refcnt);
    1179           0 :                 if (thread_is_scheduled(nhe->timer))
    1180           0 :                         json_object_string_add(
    1181             :                                 json, "timeToDeletion",
    1182           0 :                                 thread_timer_to_hhmmss(time_left,
    1183             :                                                        sizeof(time_left),
    1184             :                                                        nhe->timer));
    1185           0 :                 json_object_string_add(json, "uptime", up_str);
    1186           0 :                 json_object_string_add(json, "vrf",
    1187             :                                        vrf_id_to_name(nhe->vrf_id));
    1188             : 
    1189             :         } else {
    1190           0 :                 vty_out(vty, "ID: %u (%s)\n", nhe->id,
    1191           0 :                         zebra_route_string(nhe->type));
    1192           0 :                 vty_out(vty, "     RefCnt: %u", nhe->refcnt);
    1193           0 :                 if (thread_is_scheduled(nhe->timer))
    1194           0 :                         vty_out(vty, " Time to Deletion: %s",
    1195             :                                 thread_timer_to_hhmmss(time_left,
    1196             :                                                        sizeof(time_left),
    1197             :                                                        nhe->timer));
    1198           0 :                 vty_out(vty, "\n");
    1199             : 
    1200           0 :                 vty_out(vty, "     Uptime: %s\n", up_str);
    1201           0 :                 vty_out(vty, "     VRF: %s\n", vrf_id_to_name(nhe->vrf_id));
    1202             :         }
    1203             : 
    1204           0 :         if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)) {
    1205           0 :                 if (json)
    1206           0 :                         json_object_boolean_true_add(json, "valid");
    1207             :                 else
    1208           0 :                         vty_out(vty, "     Valid");
    1209             : 
    1210           0 :                 if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED)) {
    1211           0 :                         if (json)
    1212           0 :                                 json_object_boolean_true_add(json, "installed");
    1213             :                         else
    1214           0 :                                 vty_out(vty, ", Installed");
    1215             :                 }
    1216           0 :                 if (!json)
    1217           0 :                         vty_out(vty, "\n");
    1218             :         }
    1219           0 :         if (nhe->ifp) {
    1220           0 :                 if (json)
    1221           0 :                         json_object_int_add(json, "interfaceIndex",
    1222           0 :                                             nhe->ifp->ifindex);
    1223             :                 else
    1224           0 :                         vty_out(vty, "     Interface Index: %d\n",
    1225             :                                 nhe->ifp->ifindex);
    1226             :         }
    1227             : 
    1228           0 :         if (!zebra_nhg_depends_is_empty(nhe)) {
    1229           0 :                 if (json)
    1230           0 :                         json_depends = json_object_new_array();
    1231             :                 else
    1232           0 :                         vty_out(vty, "     Depends:");
    1233           0 :                 frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
    1234           0 :                         if (json_depends)
    1235           0 :                                 json_object_array_add(
    1236             :                                         json_depends,
    1237             :                                         json_object_new_int(
    1238           0 :                                                 rb_node_dep->nhe->id));
    1239             :                         else
    1240           0 :                                 vty_out(vty, " (%u)", rb_node_dep->nhe->id);
    1241             :                 }
    1242           0 :                 if (!json_depends)
    1243           0 :                         vty_out(vty, "\n");
    1244             :                 else
    1245           0 :                         json_object_object_add(json, "depends", json_depends);
    1246             :         }
    1247             : 
    1248             :         /* Output nexthops */
    1249           0 :         if (json)
    1250           0 :                 json_nexthop_array = json_object_new_array();
    1251             : 
    1252             : 
    1253           0 :         for (ALL_NEXTHOPS(nhe->nhg, nexthop)) {
    1254           0 :                 if (json_nexthop_array) {
    1255           0 :                         json_nexthops = json_object_new_object();
    1256           0 :                         show_nexthop_json_helper(json_nexthops, nexthop, NULL);
    1257             :                 } else {
    1258           0 :                         if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
    1259           0 :                                 vty_out(vty, "          ");
    1260             :                         else
    1261             :                                 /* Make recursive nexthops a bit more clear */
    1262           0 :                                 vty_out(vty, "       ");
    1263           0 :                         show_route_nexthop_helper(vty, NULL, nexthop);
    1264             :                 }
    1265             : 
    1266           0 :                 if (nhe->backup_info == NULL || nhe->backup_info->nhe == NULL) {
    1267           0 :                         if (CHECK_FLAG(nexthop->flags,
    1268             :                                        NEXTHOP_FLAG_HAS_BACKUP)) {
    1269           0 :                                 if (json)
    1270           0 :                                         json_object_int_add(
    1271             :                                                 json_nexthops, "backup",
    1272           0 :                                                 nexthop->backup_idx[0]);
    1273             :                                 else
    1274           0 :                                         vty_out(vty, " [backup %d]",
    1275           0 :                                                 nexthop->backup_idx[0]);
    1276             :                         }
    1277             : 
    1278           0 :                         if (!json)
    1279           0 :                                 vty_out(vty, "\n");
    1280             :                         else
    1281           0 :                                 json_object_array_add(json_nexthop_array,
    1282             :                                                       json_nexthops);
    1283             : 
    1284           0 :                         continue;
    1285             :                 }
    1286             : 
    1287           0 :                 if (!json) {
    1288             :                         /* TODO -- print more useful backup info */
    1289           0 :                         if (CHECK_FLAG(nexthop->flags,
    1290             :                                        NEXTHOP_FLAG_HAS_BACKUP)) {
    1291           0 :                                 int i;
    1292             : 
    1293           0 :                                 vty_out(vty, "[backup");
    1294           0 :                                 for (i = 0; i < nexthop->backup_num; i++)
    1295           0 :                                         vty_out(vty, " %d",
    1296           0 :                                                 nexthop->backup_idx[i]);
    1297           0 :                                 vty_out(vty, "]");
    1298             :                         }
    1299           0 :                         vty_out(vty, "\n");
    1300             :                 } else {
    1301           0 :                         json_object_array_add(json_nexthop_array,
    1302             :                                               json_nexthops);
    1303             :                 }
    1304             :         }
    1305             : 
    1306           0 :         if (json)
    1307           0 :                 json_object_object_add(json, "nexthops", json_nexthop_array);
    1308             : 
    1309             :         /* Output backup nexthops (if any) */
    1310           0 :         backup_nhg = zebra_nhg_get_backup_nhg(nhe);
    1311           0 :         if (backup_nhg) {
    1312           0 :                 if (json)
    1313           0 :                         json_backup_nexthop_array = json_object_new_array();
    1314             :                 else
    1315           0 :                         vty_out(vty, "     Backups:\n");
    1316             : 
    1317           0 :                 for (ALL_NEXTHOPS_PTR(backup_nhg, nexthop)) {
    1318           0 :                         if (json_backup_nexthop_array) {
    1319           0 :                                 json_backup_nexthops = json_object_new_object();
    1320           0 :                                 show_nexthop_json_helper(json_backup_nexthops,
    1321             :                                                          nexthop, NULL);
    1322           0 :                                 json_object_array_add(json_backup_nexthop_array,
    1323             :                                                       json_backup_nexthops);
    1324             :                         } else {
    1325             : 
    1326           0 :                                 if (!CHECK_FLAG(nexthop->flags,
    1327             :                                                 NEXTHOP_FLAG_RECURSIVE))
    1328           0 :                                         vty_out(vty, "          ");
    1329             :                                 else
    1330             :                                         /* Make recursive nexthops a bit more
    1331             :                                          * clear
    1332             :                                          */
    1333           0 :                                         vty_out(vty, "       ");
    1334           0 :                                 show_route_nexthop_helper(vty, NULL, nexthop);
    1335           0 :                                 vty_out(vty, "\n");
    1336             :                         }
    1337             :                 }
    1338             : 
    1339           0 :                 if (json)
    1340           0 :                         json_object_object_add(json, "backupNexthops",
    1341             :                                                json_backup_nexthop_array);
    1342             :         }
    1343             : 
    1344           0 :         if (!zebra_nhg_dependents_is_empty(nhe)) {
    1345           0 :                 if (json)
    1346           0 :                         json_dependants = json_object_new_array();
    1347             :                 else
    1348           0 :                         vty_out(vty, "     Dependents:");
    1349           0 :                 frr_each(nhg_connected_tree, &nhe->nhg_dependents,
    1350             :                           rb_node_dep) {
    1351           0 :                         if (json)
    1352           0 :                                 json_object_array_add(
    1353             :                                         json_dependants,
    1354             :                                         json_object_new_int(
    1355           0 :                                                 rb_node_dep->nhe->id));
    1356             :                         else
    1357           0 :                                 vty_out(vty, " (%u)", rb_node_dep->nhe->id);
    1358             :                 }
    1359           0 :                 if (json)
    1360           0 :                         json_object_object_add(json, "dependents",
    1361             :                                                json_dependants);
    1362             :                 else
    1363           0 :                         vty_out(vty, "\n");
    1364             :         }
    1365             : 
    1366           0 :         if (nhe->nhg.nhgr.buckets) {
    1367           0 :                 if (json) {
    1368           0 :                         json_object_int_add(json, "buckets",
    1369             :                                             nhe->nhg.nhgr.buckets);
    1370           0 :                         json_object_int_add(json, "idleTimer",
    1371           0 :                                             nhe->nhg.nhgr.idle_timer);
    1372           0 :                         json_object_int_add(json, "unbalancedTimer",
    1373           0 :                                             nhe->nhg.nhgr.unbalanced_timer);
    1374           0 :                         json_object_int_add(json, "unbalancedTime",
    1375           0 :                                             nhe->nhg.nhgr.unbalanced_time);
    1376             :                 } else {
    1377           0 :                         vty_out(vty,
    1378             :                                 "     Buckets: %u Idle Timer: %u Unbalanced Timer: %u Unbalanced time: %" PRIu64
    1379             :                                 "\n",
    1380             :                                 nhe->nhg.nhgr.buckets, nhe->nhg.nhgr.idle_timer,
    1381             :                                 nhe->nhg.nhgr.unbalanced_timer,
    1382             :                                 nhe->nhg.nhgr.unbalanced_time);
    1383             :                 }
    1384             :         }
    1385             : 
    1386           0 :         if (json_nhe_hdr)
    1387           0 :                 json_object_object_addf(json_nhe_hdr, json, "%u", nhe->id);
    1388           0 : }
    1389             : 
    1390           0 : static int show_nexthop_group_id_cmd_helper(struct vty *vty, uint32_t id,
    1391             :                                             json_object *json)
    1392             : {
    1393           0 :         struct nhg_hash_entry *nhe = NULL;
    1394             : 
    1395           0 :         nhe = zebra_nhg_lookup_id(id);
    1396             : 
    1397           0 :         if (nhe)
    1398           0 :                 show_nexthop_group_out(vty, nhe, json);
    1399             :         else {
    1400           0 :                 if (json)
    1401           0 :                         vty_json(vty, json);
    1402             :                 else
    1403           0 :                         vty_out(vty, "Nexthop Group ID: %u does not exist\n",
    1404             :                                 id);
    1405           0 :                 return CMD_WARNING;
    1406             :         }
    1407             : 
    1408           0 :         if (json)
    1409           0 :                 vty_json(vty, json);
    1410             : 
    1411             :         return CMD_SUCCESS;
    1412             : }
    1413             : 
    1414             : /* Helper function for iteration through the hash of nexthop-groups/nhe-s */
    1415             : 
    1416             : struct nhe_show_context {
    1417             :         struct vty *vty;
    1418             :         vrf_id_t vrf_id;
    1419             :         afi_t afi;
    1420             :         int type;
    1421             :         json_object *json;
    1422             : };
    1423             : 
    1424           0 : static int nhe_show_walker(struct hash_bucket *bucket, void *arg)
    1425             : {
    1426           0 :         struct nhe_show_context *ctx = arg;
    1427           0 :         struct nhg_hash_entry *nhe;
    1428             : 
    1429           0 :         nhe = bucket->data; /* We won't be offered NULL buckets */
    1430             : 
    1431           0 :         if (ctx->afi && nhe->afi != ctx->afi)
    1432           0 :                 goto done;
    1433             : 
    1434           0 :         if (ctx->vrf_id && nhe->vrf_id != ctx->vrf_id)
    1435           0 :                 goto done;
    1436             : 
    1437           0 :         if (ctx->type && nhe->type != ctx->type)
    1438           0 :                 goto done;
    1439             : 
    1440           0 :         show_nexthop_group_out(ctx->vty, nhe, ctx->json);
    1441             : 
    1442           0 : done:
    1443           0 :         return HASHWALK_CONTINUE;
    1444             : }
    1445             : 
    1446           0 : static void show_nexthop_group_cmd_helper(struct vty *vty,
    1447             :                                           struct zebra_vrf *zvrf, afi_t afi,
    1448             :                                           int type, json_object *json)
    1449             : {
    1450           0 :         struct nhe_show_context ctx;
    1451             : 
    1452           0 :         ctx.vty = vty;
    1453           0 :         ctx.afi = afi;
    1454           0 :         ctx.vrf_id = zvrf->vrf->vrf_id;
    1455           0 :         ctx.type = type;
    1456           0 :         ctx.json = json;
    1457             : 
    1458           0 :         hash_walk(zrouter.nhgs_id, nhe_show_walker, &ctx);
    1459           0 : }
    1460             : 
    1461           0 : static void if_nexthop_group_dump_vty(struct vty *vty, struct interface *ifp)
    1462             : {
    1463           0 :         struct zebra_if *zebra_if = NULL;
    1464           0 :         struct nhg_connected *rb_node_dep = NULL;
    1465             : 
    1466           0 :         zebra_if = ifp->info;
    1467             : 
    1468           0 :         if (!if_nhg_dependents_is_empty(ifp)) {
    1469           0 :                 vty_out(vty, "Interface %s:\n", ifp->name);
    1470             : 
    1471           0 :                 frr_each(nhg_connected_tree, &zebra_if->nhg_dependents,
    1472             :                           rb_node_dep) {
    1473           0 :                         vty_out(vty, "   ");
    1474           0 :                         show_nexthop_group_out(vty, rb_node_dep->nhe, NULL);
    1475             :                 }
    1476             :         }
    1477           0 : }
    1478             : 
    1479           0 : DEFPY (show_interface_nexthop_group,
    1480             :        show_interface_nexthop_group_cmd,
    1481             :        "show interface [IFNAME$if_name] nexthop-group",
    1482             :        SHOW_STR
    1483             :        "Interface status and configuration\n"
    1484             :        "Interface name\n"
    1485             :        "Show Nexthop Groups\n")
    1486             : {
    1487           0 :         struct vrf *vrf = NULL;
    1488           0 :         struct interface *ifp = NULL;
    1489           0 :         bool found = false;
    1490             : 
    1491           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    1492           0 :                 if (if_name) {
    1493           0 :                         ifp = if_lookup_by_name(if_name, vrf->vrf_id);
    1494           0 :                         if (ifp) {
    1495           0 :                                 if_nexthop_group_dump_vty(vty, ifp);
    1496           0 :                                 found = true;
    1497             :                         }
    1498             :                 } else {
    1499           0 :                         FOR_ALL_INTERFACES (vrf, ifp)
    1500           0 :                                 if_nexthop_group_dump_vty(vty, ifp);
    1501             :                         found = true;
    1502             :                 }
    1503             :         }
    1504             : 
    1505           0 :         if (!found) {
    1506           0 :                 vty_out(vty, "%% Can't find interface %s\n", if_name);
    1507           0 :                 return CMD_WARNING;
    1508             :         }
    1509             : 
    1510             :         return CMD_SUCCESS;
    1511             : }
    1512             : 
    1513           0 : DEFPY(show_nexthop_group,
    1514             :       show_nexthop_group_cmd,
    1515             :       "show nexthop-group rib <(0-4294967295)$id|[singleton <ip$v4|ipv6$v6>] [<kernel|zebra|bgp|sharp>$type_str] [vrf <NAME$vrf_name|all$vrf_all>]> [json]",
    1516             :       SHOW_STR
    1517             :       "Show Nexthop Groups\n"
    1518             :       "RIB information\n"
    1519             :       "Nexthop Group ID\n"
    1520             :       "Show Singleton Nexthop-Groups\n"
    1521             :       IP_STR
    1522             :       IP6_STR
    1523             :       "Kernel (not installed via the zebra RIB)\n"
    1524             :       "Zebra (implicitly created by zebra)\n"
    1525             :       "Border Gateway Protocol (BGP)\n"
    1526             :       "Super Happy Advanced Routing Protocol (SHARP)\n"
    1527             :       VRF_FULL_CMD_HELP_STR
    1528             :       JSON_STR)
    1529             : {
    1530             : 
    1531           0 :         struct zebra_vrf *zvrf = NULL;
    1532           0 :         afi_t afi = AFI_UNSPEC;
    1533           0 :         int type = 0;
    1534           0 :         bool uj = use_json(argc, argv);
    1535           0 :         json_object *json = NULL;
    1536           0 :         json_object *json_vrf = NULL;
    1537             : 
    1538           0 :         if (uj)
    1539           0 :                 json = json_object_new_object();
    1540             : 
    1541           0 :         if (id)
    1542           0 :                 return show_nexthop_group_id_cmd_helper(vty, id, json);
    1543             : 
    1544           0 :         if (v4)
    1545             :                 afi = AFI_IP;
    1546           0 :         else if (v6)
    1547           0 :                 afi = AFI_IP6;
    1548             : 
    1549           0 :         if (type_str) {
    1550           0 :                 type = proto_redistnum((afi ? afi : AFI_IP), type_str);
    1551           0 :                 if (type < 0) {
    1552             :                         /* assume zebra */
    1553           0 :                         type = ZEBRA_ROUTE_NHG;
    1554             :                 }
    1555             :         }
    1556             : 
    1557           0 :         if (!vrf_is_backend_netns() && (vrf_name || vrf_all)) {
    1558           0 :                 if (uj)
    1559           0 :                         vty_json(vty, json);
    1560             :                 else
    1561           0 :                         vty_out(vty,
    1562             :                                 "VRF subcommand does not make any sense in l3mdev based vrf's\n");
    1563           0 :                 return CMD_WARNING;
    1564             :         }
    1565             : 
    1566           0 :         if (vrf_all) {
    1567           0 :                 struct vrf *vrf;
    1568             : 
    1569           0 :                 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    1570           0 :                         struct zebra_vrf *zvrf;
    1571             : 
    1572           0 :                         zvrf = vrf->info;
    1573           0 :                         if (!zvrf)
    1574           0 :                                 continue;
    1575           0 :                         if (uj)
    1576           0 :                                 json_vrf = json_object_new_object();
    1577             :                         else
    1578           0 :                                 vty_out(vty, "VRF: %s\n", vrf->name);
    1579             : 
    1580           0 :                         show_nexthop_group_cmd_helper(vty, zvrf, afi, type,
    1581             :                                                       json_vrf);
    1582           0 :                         if (uj)
    1583           0 :                                 json_object_object_add(json, vrf->name,
    1584             :                                                        json_vrf);
    1585             :                 }
    1586             : 
    1587           0 :                 if (uj)
    1588           0 :                         vty_json(vty, json);
    1589             : 
    1590           0 :                 return CMD_SUCCESS;
    1591             :         }
    1592             : 
    1593           0 :         if (vrf_name)
    1594           0 :                 zvrf = zebra_vrf_lookup_by_name(vrf_name);
    1595             :         else
    1596           0 :                 zvrf = zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME);
    1597             : 
    1598           0 :         if (!zvrf) {
    1599           0 :                 if (uj)
    1600           0 :                         vty_json(vty, json);
    1601             :                 else
    1602           0 :                         vty_out(vty, "%% VRF '%s' specified does not exist\n",
    1603             :                                 vrf_name);
    1604           0 :                 return CMD_WARNING;
    1605             :         }
    1606             : 
    1607           0 :         show_nexthop_group_cmd_helper(vty, zvrf, afi, type, json);
    1608             : 
    1609           0 :         if (uj)
    1610           0 :                 vty_json(vty, json);
    1611             : 
    1612             :         return CMD_SUCCESS;
    1613             : }
    1614             : 
    1615           0 : DEFPY_HIDDEN(nexthop_group_use_enable,
    1616             :              nexthop_group_use_enable_cmd,
    1617             :              "[no] zebra nexthop kernel enable",
    1618             :              NO_STR
    1619             :              ZEBRA_STR
    1620             :              "Nexthop configuration \n"
    1621             :              "Configure use of kernel nexthops\n"
    1622             :              "Enable kernel nexthops\n")
    1623             : {
    1624           0 :         zebra_nhg_enable_kernel_nexthops(!no);
    1625           0 :         return CMD_SUCCESS;
    1626             : }
    1627             : 
    1628           0 : DEFPY_HIDDEN(proto_nexthop_group_only, proto_nexthop_group_only_cmd,
    1629             :              "[no] zebra nexthop proto only",
    1630             :              NO_STR ZEBRA_STR
    1631             :              "Nexthop configuration\n"
    1632             :              "Configure exclusive use of proto nexthops\n"
    1633             :              "Only use proto nexthops\n")
    1634             : {
    1635           0 :         zebra_nhg_set_proto_nexthops_only(!no);
    1636           0 :         return CMD_SUCCESS;
    1637             : }
    1638             : 
    1639           0 : DEFPY_HIDDEN(backup_nexthop_recursive_use_enable,
    1640             :              backup_nexthop_recursive_use_enable_cmd,
    1641             :              "[no] zebra nexthop resolve-via-backup",
    1642             :              NO_STR
    1643             :              ZEBRA_STR
    1644             :              "Nexthop configuration \n"
    1645             :              "Configure use of backup nexthops in recursive resolution\n")
    1646             : {
    1647           0 :         zebra_nhg_set_recursive_use_backups(!no);
    1648           0 :         return CMD_SUCCESS;
    1649             : }
    1650             : 
    1651           0 : DEFUN (no_ip_nht_default_route,
    1652             :        no_ip_nht_default_route_cmd,
    1653             :        "no ip nht resolve-via-default",
    1654             :        NO_STR
    1655             :        IP_STR
    1656             :        "Filter Next Hop tracking route resolution\n"
    1657             :        "Resolve via default route\n")
    1658             : {
    1659           0 :         ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
    1660             : 
    1661           0 :         if (!zvrf)
    1662             :                 return CMD_WARNING;
    1663             : 
    1664           0 :         if (!zvrf->zebra_rnh_ip_default_route)
    1665             :                 return CMD_SUCCESS;
    1666             : 
    1667           0 :         zvrf->zebra_rnh_ip_default_route = false;
    1668           0 :         zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST);
    1669           0 :         return CMD_SUCCESS;
    1670             : }
    1671             : 
    1672           0 : DEFUN (ipv6_nht_default_route,
    1673             :        ipv6_nht_default_route_cmd,
    1674             :        "ipv6 nht resolve-via-default",
    1675             :        IP6_STR
    1676             :        "Filter Next Hop tracking route resolution\n"
    1677             :        "Resolve via default route\n")
    1678             : {
    1679           0 :         ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
    1680             : 
    1681           0 :         if (!zvrf)
    1682             :                 return CMD_WARNING;
    1683             : 
    1684           0 :         if (zvrf->zebra_rnh_ipv6_default_route)
    1685             :                 return CMD_SUCCESS;
    1686             : 
    1687           0 :         zvrf->zebra_rnh_ipv6_default_route = true;
    1688           0 :         zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST);
    1689           0 :         return CMD_SUCCESS;
    1690             : }
    1691             : 
    1692           0 : DEFUN (no_ipv6_nht_default_route,
    1693             :        no_ipv6_nht_default_route_cmd,
    1694             :        "no ipv6 nht resolve-via-default",
    1695             :        NO_STR
    1696             :        IP6_STR
    1697             :        "Filter Next Hop tracking route resolution\n"
    1698             :        "Resolve via default route\n")
    1699             : {
    1700           0 :         ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
    1701             : 
    1702           0 :         if (!zvrf)
    1703             :                 return CMD_WARNING;
    1704             : 
    1705           0 :         if (!zvrf->zebra_rnh_ipv6_default_route)
    1706             :                 return CMD_SUCCESS;
    1707             : 
    1708           0 :         zvrf->zebra_rnh_ipv6_default_route = false;
    1709           0 :         zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST);
    1710           0 :         return CMD_SUCCESS;
    1711             : }
    1712             : 
    1713           0 : DEFPY_HIDDEN(rnh_hide_backups, rnh_hide_backups_cmd,
    1714             :              "[no] ip nht hide-backup-events",
    1715             :              NO_STR
    1716             :              IP_STR
    1717             :              "Nexthop-tracking configuration\n"
    1718             :              "Hide notification about backup nexthops\n")
    1719             : {
    1720           0 :         rnh_set_hide_backups(!no);
    1721           0 :         return CMD_SUCCESS;
    1722             : }
    1723             : 
    1724           0 : DEFPY (show_route,
    1725             :        show_route_cmd,
    1726             :        "show\
    1727             :          <\
    1728             :           ip$ipv4 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
    1729             :           [vrf <NAME$vrf_name|all$vrf_all>]\
    1730             :            [{\
    1731             :             tag (1-4294967295)\
    1732             :             |A.B.C.D/M$prefix longer-prefixes\
    1733             :             |supernets-only$supernets_only\
    1734             :            }]\
    1735             :            [<\
    1736             :             " FRR_IP_REDIST_STR_ZEBRA "$type_str\
    1737             :             |ospf$type_str (1-65535)$ospf_instance_id\
    1738             :            >]\
    1739             :           |ipv6$ipv6 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
    1740             :           [vrf <NAME$vrf_name|all$vrf_all>]\
    1741             :            [{\
    1742             :             tag (1-4294967295)\
    1743             :             |X:X::X:X/M$prefix longer-prefixes\
    1744             :            }]\
    1745             :            [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
    1746             :          >\
    1747             :         [<json$json|nexthop-group$ng>]",
    1748             :        SHOW_STR
    1749             :        IP_STR
    1750             :        "IP forwarding table\n"
    1751             :        "IP routing table\n"
    1752             :        "Table to display\n"
    1753             :        "The table number to display\n"
    1754             :        "All tables\n"
    1755             :        VRF_FULL_CMD_HELP_STR
    1756             :        "Show only routes with tag\n"
    1757             :        "Tag value\n"
    1758             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    1759             :        "Show route matching the specified Network/Mask pair only\n"
    1760             :        "Show supernet entries only\n"
    1761             :        FRR_IP_REDIST_HELP_STR_ZEBRA
    1762             :        "Open Shortest Path First (OSPFv2)\n"
    1763             :        "Instance ID\n"
    1764             :        IPV6_STR
    1765             :        "IP forwarding table\n"
    1766             :        "IP routing table\n"
    1767             :        "Table to display\n"
    1768             :        "The table number to display\n"
    1769             :        "All tables\n"
    1770             :        VRF_FULL_CMD_HELP_STR
    1771             :        "Show only routes with tag\n"
    1772             :        "Tag value\n"
    1773             :        "IPv6 prefix\n"
    1774             :        "Show route matching the specified Network/Mask pair only\n"
    1775             :        FRR_IP6_REDIST_HELP_STR_ZEBRA
    1776             :        JSON_STR
    1777             :        "Nexthop Group Information\n")
    1778             : {
    1779           0 :         afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
    1780           0 :         struct vrf *vrf;
    1781           0 :         int type = 0;
    1782           0 :         struct zebra_vrf *zvrf;
    1783           0 :         struct route_show_ctx ctx = {
    1784           0 :                 .multi = vrf_all || table_all,
    1785             :         };
    1786             : 
    1787           0 :         if (!vrf_is_backend_netns()) {
    1788           0 :                 if ((vrf_all || vrf_name) && (table || table_all)) {
    1789           0 :                         if (!!json)
    1790           0 :                                 vty_out(vty, "{}\n");
    1791             :                         else {
    1792           0 :                                 vty_out(vty, "Linux vrf backend already points to table id\n");
    1793           0 :                                 vty_out(vty, "Either remove table parameter or vrf parameter\n");
    1794             :                         }
    1795           0 :                         return CMD_SUCCESS;
    1796             :                 }
    1797             :         }
    1798           0 :         if (type_str) {
    1799           0 :                 type = proto_redistnum(afi, type_str);
    1800           0 :                 if (type < 0) {
    1801           0 :                         vty_out(vty, "Unknown route type\n");
    1802           0 :                         return CMD_WARNING;
    1803             :                 }
    1804             :         }
    1805             : 
    1806           0 :         if (vrf_all) {
    1807           0 :                 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    1808           0 :                         if ((zvrf = vrf->info) == NULL
    1809           0 :                             || (zvrf->table[afi][SAFI_UNICAST] == NULL))
    1810           0 :                                 continue;
    1811             : 
    1812           0 :                         if (table_all)
    1813           0 :                                 do_show_ip_route_all(
    1814             :                                         vty, zvrf, afi, !!fib, !!json, tag,
    1815             :                                         prefix_str ? prefix : NULL,
    1816             :                                         !!supernets_only, type,
    1817             :                                         ospf_instance_id, !!ng, &ctx);
    1818             :                         else
    1819           0 :                                 do_show_ip_route(
    1820             :                                         vty, zvrf_name(zvrf), afi, SAFI_UNICAST,
    1821             :                                         !!fib, !!json, tag,
    1822             :                                         prefix_str ? prefix : NULL,
    1823             :                                         !!supernets_only, type,
    1824             :                                         ospf_instance_id, table, !!ng, &ctx);
    1825             :                 }
    1826             :         } else {
    1827           0 :                 vrf_id_t vrf_id = VRF_DEFAULT;
    1828             : 
    1829           0 :                 if (vrf_name)
    1830           0 :                         VRF_GET_ID(vrf_id, vrf_name, !!json);
    1831           0 :                 vrf = vrf_lookup_by_id(vrf_id);
    1832           0 :                 if (!vrf)
    1833             :                         return CMD_SUCCESS;
    1834             : 
    1835           0 :                 zvrf = vrf->info;
    1836           0 :                 if (!zvrf)
    1837             :                         return CMD_SUCCESS;
    1838             : 
    1839           0 :                 if (table_all)
    1840           0 :                         do_show_ip_route_all(vty, zvrf, afi, !!fib, !!json, tag,
    1841             :                                              prefix_str ? prefix : NULL,
    1842             :                                              !!supernets_only, type,
    1843             :                                              ospf_instance_id, !!ng, &ctx);
    1844             :                 else
    1845           0 :                         do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST,
    1846             :                                          !!fib, !!json, tag,
    1847             :                                          prefix_str ? prefix : NULL,
    1848             :                                          !!supernets_only, type,
    1849             :                                          ospf_instance_id, table, !!ng, &ctx);
    1850             :         }
    1851             : 
    1852             :         return CMD_SUCCESS;
    1853             : }
    1854             : 
    1855             : ALIAS_HIDDEN (show_route,
    1856             :               show_ro_cmd,
    1857             :               "show <ip$ipv4|ipv6$ipv6> ro",
    1858             :               SHOW_STR
    1859             :               IP_STR
    1860             :               IPV6_STR
    1861             :               "IP routing table\n");
    1862             : 
    1863             : 
    1864           0 : DEFPY (show_route_detail,
    1865             :        show_route_detail_cmd,
    1866             :        "show\
    1867             :          <\
    1868             :           ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
    1869             :           <\
    1870             :            A.B.C.D$address\
    1871             :            |A.B.C.D/M$prefix\
    1872             :           >\
    1873             :           |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
    1874             :           <\
    1875             :            X:X::X:X$address\
    1876             :            |X:X::X:X/M$prefix\
    1877             :           >\
    1878             :          >\
    1879             :          [json$json] [nexthop-group$ng]",
    1880             :        SHOW_STR
    1881             :        IP_STR
    1882             :        "IP forwarding table\n"
    1883             :        "IP routing table\n"
    1884             :        VRF_FULL_CMD_HELP_STR
    1885             :        "Network in the IP routing table to display\n"
    1886             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    1887             :        IP6_STR
    1888             :        "IPv6 forwarding table\n"
    1889             :        "IPv6 routing table\n"
    1890             :        VRF_FULL_CMD_HELP_STR
    1891             :        "IPv6 Address\n"
    1892             :        "IPv6 prefix\n"
    1893             :        JSON_STR
    1894             :        "Nexthop Group Information\n")
    1895             : {
    1896           0 :         afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
    1897           0 :         struct route_table *table;
    1898           0 :         struct prefix p;
    1899           0 :         struct route_node *rn;
    1900           0 :         bool use_fib = !!fib;
    1901           0 :         rib_dest_t *dest;
    1902           0 :         bool network_found = false;
    1903           0 :         bool show_ng = !!ng;
    1904             : 
    1905           0 :         if (address_str)
    1906           0 :                 prefix_str = address_str;
    1907           0 :         if (str2prefix(prefix_str, &p) < 0) {
    1908           0 :                 vty_out(vty, "%% Malformed address\n");
    1909           0 :                 return CMD_WARNING;
    1910             :         }
    1911             : 
    1912           0 :         if (vrf_all) {
    1913           0 :                 struct vrf *vrf;
    1914           0 :                 struct zebra_vrf *zvrf;
    1915             : 
    1916           0 :                 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    1917           0 :                         if ((zvrf = vrf->info) == NULL
    1918           0 :                             || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
    1919           0 :                                 continue;
    1920             : 
    1921           0 :                         rn = route_node_match(table, &p);
    1922           0 :                         if (!rn)
    1923           0 :                                 continue;
    1924           0 :                         if (!address_str && rn->p.prefixlen != p.prefixlen) {
    1925           0 :                                 route_unlock_node(rn);
    1926           0 :                                 continue;
    1927             :                         }
    1928             : 
    1929           0 :                         dest = rib_dest_from_rnode(rn);
    1930           0 :                         if (use_fib && !dest->selected_fib) {
    1931           0 :                                 route_unlock_node(rn);
    1932           0 :                                 continue;
    1933             :                         }
    1934             : 
    1935           0 :                         network_found = true;
    1936           0 :                         if (json)
    1937           0 :                                 vty_show_ip_route_detail_json(vty, rn, use_fib);
    1938             :                         else
    1939           0 :                                 vty_show_ip_route_detail(vty, rn, 0, use_fib,
    1940             :                                                          show_ng);
    1941             : 
    1942           0 :                         route_unlock_node(rn);
    1943             :                 }
    1944             : 
    1945           0 :                 if (!network_found) {
    1946           0 :                         if (json)
    1947           0 :                                 vty_out(vty, "{}\n");
    1948             :                         else {
    1949           0 :                                 if (use_fib)
    1950           0 :                                         vty_out(vty,
    1951             :                                                 "%% Network not in FIB\n");
    1952             :                                 else
    1953           0 :                                         vty_out(vty,
    1954             :                                                 "%% Network not in RIB\n");
    1955             :                         }
    1956           0 :                         return CMD_WARNING;
    1957             :                 }
    1958             :         } else {
    1959           0 :                 vrf_id_t vrf_id = VRF_DEFAULT;
    1960             : 
    1961           0 :                 if (vrf_name)
    1962           0 :                         VRF_GET_ID(vrf_id, vrf_name, false);
    1963             : 
    1964           0 :                 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
    1965           0 :                 if (!table)
    1966             :                         return CMD_SUCCESS;
    1967             : 
    1968           0 :                 rn = route_node_match(table, &p);
    1969           0 :                 if (rn)
    1970           0 :                         dest = rib_dest_from_rnode(rn);
    1971             : 
    1972           0 :                 if (!rn || (!address_str && rn->p.prefixlen != p.prefixlen) ||
    1973           0 :                         (use_fib && dest && !dest->selected_fib)) {
    1974           0 :                         if (json)
    1975           0 :                                 vty_out(vty, "{}\n");
    1976             :                         else {
    1977           0 :                                 if (use_fib)
    1978           0 :                                         vty_out(vty,
    1979             :                                                 "%% Network not in FIB\n");
    1980             :                                 else
    1981           0 :                                         vty_out(vty,
    1982             :                                                 "%% Network not in table\n");
    1983             :                         }
    1984           0 :                         if (rn)
    1985           0 :                                 route_unlock_node(rn);
    1986           0 :                         return CMD_WARNING;
    1987             :                 }
    1988             : 
    1989           0 :                 if (json)
    1990           0 :                         vty_show_ip_route_detail_json(vty, rn, use_fib);
    1991             :                 else
    1992           0 :                         vty_show_ip_route_detail(vty, rn, 0, use_fib, show_ng);
    1993             : 
    1994           0 :                 route_unlock_node(rn);
    1995             :         }
    1996             : 
    1997             :         return CMD_SUCCESS;
    1998             : }
    1999             : 
    2000           0 : DEFPY (show_route_summary,
    2001             :        show_route_summary_cmd,
    2002             :        "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
    2003             :             summary [table (1-4294967295)$table_id] [prefix$prefix] [json]",
    2004             :        SHOW_STR
    2005             :        IP_STR
    2006             :        IP6_STR
    2007             :        "IP routing table\n"
    2008             :        VRF_FULL_CMD_HELP_STR
    2009             :        "Summary of all routes\n"
    2010             :        "Table to display summary for\n"
    2011             :        "The table number\n"
    2012             :        "Prefix routes\n"
    2013             :        JSON_STR)
    2014             : {
    2015           0 :         afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
    2016           0 :         struct route_table *table;
    2017           0 :         bool uj = use_json(argc, argv);
    2018             : 
    2019           0 :         if (vrf_all) {
    2020           0 :                 struct vrf *vrf;
    2021           0 :                 struct zebra_vrf *zvrf;
    2022             : 
    2023           0 :                 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    2024           0 :                         if ((zvrf = vrf->info) == NULL)
    2025           0 :                                 continue;
    2026             : 
    2027           0 :                         if (table_id == 0)
    2028           0 :                                 table = zebra_vrf_table(afi, SAFI_UNICAST,
    2029           0 :                                                         zvrf->vrf->vrf_id);
    2030             :                         else
    2031           0 :                                 table = zebra_vrf_lookup_table_with_table_id(
    2032           0 :                                         afi, SAFI_UNICAST, zvrf->vrf->vrf_id,
    2033             :                                         table_id);
    2034             : 
    2035           0 :                         if (!table)
    2036           0 :                                 continue;
    2037             : 
    2038           0 :                         if (prefix)
    2039           0 :                                 vty_show_ip_route_summary_prefix(vty, table,
    2040             :                                                                  uj);
    2041             :                         else
    2042           0 :                                 vty_show_ip_route_summary(vty, table, uj);
    2043             :                 }
    2044             :         } else {
    2045           0 :                 vrf_id_t vrf_id = VRF_DEFAULT;
    2046             : 
    2047           0 :                 if (vrf_name)
    2048           0 :                         VRF_GET_ID(vrf_id, vrf_name, false);
    2049             : 
    2050           0 :                 if (table_id == 0)
    2051           0 :                         table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
    2052             :                 else
    2053           0 :                         table = zebra_vrf_lookup_table_with_table_id(
    2054             :                                 afi, SAFI_UNICAST, vrf_id, table_id);
    2055           0 :                 if (!table)
    2056             :                         return CMD_SUCCESS;
    2057             : 
    2058           0 :                 if (prefix)
    2059           0 :                         vty_show_ip_route_summary_prefix(vty, table, uj);
    2060             :                 else
    2061           0 :                         vty_show_ip_route_summary(vty, table, uj);
    2062             :         }
    2063             : 
    2064             :         return CMD_SUCCESS;
    2065             : }
    2066             : 
    2067           0 : DEFUN_HIDDEN (show_route_zebra_dump,
    2068             :               show_route_zebra_dump_cmd,
    2069             :               "show <ip|ipv6> zebra route dump [vrf VRFNAME]",
    2070             :               SHOW_STR
    2071             :               IP_STR
    2072             :               IP6_STR
    2073             :               "Zebra daemon\n"
    2074             :               "Routing table\n"
    2075             :               "All information\n"
    2076             :               VRF_CMD_HELP_STR)
    2077             : {
    2078           0 :         afi_t afi = AFI_IP;
    2079           0 :         struct route_table *table;
    2080           0 :         const char *vrf_name = NULL;
    2081           0 :         int idx = 0;
    2082             : 
    2083           0 :         afi = strmatch(argv[1]->text, "ipv6") ? AFI_IP6 : AFI_IP;
    2084             : 
    2085           0 :         if (argv_find(argv, argc, "vrf", &idx))
    2086           0 :                 vrf_name = argv[++idx]->arg;
    2087             : 
    2088           0 :         if (!vrf_name) {
    2089           0 :                 struct vrf *vrf;
    2090           0 :                 struct zebra_vrf *zvrf;
    2091             : 
    2092           0 :                 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    2093           0 :                         zvrf = vrf->info;
    2094           0 :                         if ((zvrf == NULL)
    2095           0 :                             || (zvrf->table[afi][SAFI_UNICAST] == NULL))
    2096           0 :                                 continue;
    2097             : 
    2098           0 :                         table = zvrf->table[afi][SAFI_UNICAST];
    2099           0 :                         show_ip_route_dump_vty(vty, table);
    2100             :                 }
    2101             :         } else {
    2102           0 :                 vrf_id_t vrf_id = VRF_DEFAULT;
    2103             : 
    2104           0 :                 VRF_GET_ID(vrf_id, vrf_name, true);
    2105             : 
    2106           0 :                 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
    2107           0 :                 if (!table)
    2108             :                         return CMD_SUCCESS;
    2109             : 
    2110           0 :                 show_ip_route_dump_vty(vty, table);
    2111             :         }
    2112             : 
    2113             :         return CMD_SUCCESS;
    2114             : }
    2115             : 
    2116           0 : static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop,
    2117             :                                    struct route_entry *re, unsigned int num)
    2118             : {
    2119             : 
    2120           0 :         char buf[SRCDEST2STR_BUFFER];
    2121             : 
    2122           0 :         vty_out(vty, "   Nexthop %u:\n", num);
    2123           0 :         vty_out(vty, "      type: %u\n", nexthop->type);
    2124           0 :         vty_out(vty, "      flags: %u\n", nexthop->flags);
    2125           0 :         switch (nexthop->type) {
    2126           0 :         case NEXTHOP_TYPE_IPV4:
    2127             :         case NEXTHOP_TYPE_IPV4_IFINDEX:
    2128           0 :                 vty_out(vty, "      ip address: %s\n",
    2129           0 :                         inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
    2130             :                                   sizeof(buf)));
    2131           0 :                 vty_out(vty, "      afi: ipv4\n");
    2132             : 
    2133           0 :                 if (nexthop->ifindex) {
    2134           0 :                         vty_out(vty, "      interface index: %d\n",
    2135             :                                 nexthop->ifindex);
    2136           0 :                         vty_out(vty, "      interface name: %s\n",
    2137             :                                 ifindex2ifname(nexthop->ifindex,
    2138             :                                                nexthop->vrf_id));
    2139             :                 }
    2140             : 
    2141           0 :                 if (nexthop->src.ipv4.s_addr
    2142           0 :                     && (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
    2143             :                                   sizeof(buf))))
    2144           0 :                         vty_out(vty, "      source: %s\n", buf);
    2145             :                 break;
    2146           0 :         case NEXTHOP_TYPE_IPV6:
    2147             :         case NEXTHOP_TYPE_IPV6_IFINDEX:
    2148           0 :                 vty_out(vty, "      ip: %s\n",
    2149           0 :                         inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
    2150             :                                   sizeof(buf)));
    2151           0 :                 vty_out(vty, "      afi: ipv6\n");
    2152             : 
    2153           0 :                 if (nexthop->ifindex) {
    2154           0 :                         vty_out(vty, "      interface index: %d\n",
    2155             :                                 nexthop->ifindex);
    2156           0 :                         vty_out(vty, "      interface name: %s\n",
    2157             :                                 ifindex2ifname(nexthop->ifindex,
    2158             :                                                nexthop->vrf_id));
    2159             :                 }
    2160             : 
    2161           0 :                 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
    2162           0 :                         if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
    2163             :                                       sizeof(buf)))
    2164           0 :                                 vty_out(vty, "      source: %s\n", buf);
    2165             :                 }
    2166             :                 break;
    2167           0 :         case NEXTHOP_TYPE_IFINDEX:
    2168           0 :                 vty_out(vty,
    2169             :                         "      Nexthop is an interface (directly connected).\n");
    2170           0 :                 vty_out(vty, "      interface index: %d\n", nexthop->ifindex);
    2171           0 :                 vty_out(vty, "      interface name: %s\n",
    2172             :                         ifindex2ifname(nexthop->ifindex, nexthop->vrf_id));
    2173           0 :                 break;
    2174           0 :         case NEXTHOP_TYPE_BLACKHOLE:
    2175           0 :                 vty_out(vty, "      Nexthop type is blackhole.\n");
    2176             : 
    2177           0 :                 switch (nexthop->bh_type) {
    2178           0 :                 case BLACKHOLE_REJECT:
    2179           0 :                         vty_out(vty, "      Blackhole type: reject\n");
    2180           0 :                         break;
    2181           0 :                 case BLACKHOLE_ADMINPROHIB:
    2182           0 :                         vty_out(vty,
    2183             :                                 "      Blackhole type: admin-prohibited\n");
    2184           0 :                         break;
    2185           0 :                 case BLACKHOLE_NULL:
    2186           0 :                         vty_out(vty, "      Blackhole type: NULL0\n");
    2187           0 :                         break;
    2188             :                 case BLACKHOLE_UNSPEC:
    2189             :                         break;
    2190             :                 }
    2191             :                 break;
    2192             :         }
    2193           0 : }
    2194             : 
    2195           0 : static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table)
    2196             : {
    2197           0 :         struct route_node *rn;
    2198           0 :         struct route_entry *re;
    2199           0 :         char buf[SRCDEST2STR_BUFFER];
    2200           0 :         char time[20];
    2201           0 :         time_t uptime;
    2202           0 :         struct tm tm;
    2203           0 :         struct timeval tv;
    2204           0 :         struct nexthop *nexthop = NULL;
    2205           0 :         int nexthop_num = 0;
    2206             : 
    2207           0 :         vty_out(vty, "\nIPv4/IPv6 Routing table dump\n");
    2208           0 :         vty_out(vty, "----------------------------\n");
    2209             : 
    2210           0 :         for (rn = route_top(table); rn; rn = route_next(rn)) {
    2211           0 :                 RNODE_FOREACH_RE (rn, re) {
    2212           0 :                         vty_out(vty, "Route: %s\n",
    2213             :                                 srcdest_rnode2str(rn, buf, sizeof(buf)));
    2214           0 :                         vty_out(vty, "   protocol: %s\n",
    2215           0 :                                 zebra_route_string(re->type));
    2216           0 :                         vty_out(vty, "   instance: %u\n", re->instance);
    2217           0 :                         vty_out(vty, "   VRF ID: %u\n", re->vrf_id);
    2218           0 :                         vty_out(vty, "   VRF name: %s\n",
    2219             :                                 vrf_id_to_name(re->vrf_id));
    2220           0 :                         vty_out(vty, "   flags: %u\n", re->flags);
    2221             : 
    2222           0 :                         if (re->type != ZEBRA_ROUTE_CONNECT) {
    2223           0 :                                 vty_out(vty, "   distance: %u\n", re->distance);
    2224           0 :                                 vty_out(vty, "   metric: %u\n", re->metric);
    2225             :                         }
    2226             : 
    2227           0 :                         vty_out(vty, "   tag: %u\n", re->tag);
    2228             : 
    2229           0 :                         uptime = monotime(&tv);
    2230           0 :                         uptime -= re->uptime;
    2231           0 :                         gmtime_r(&uptime, &tm);
    2232             : 
    2233           0 :                         if (uptime < ONE_DAY_SECOND)
    2234           0 :                                 snprintf(time, sizeof(time), "%02d:%02d:%02d",
    2235             :                                          tm.tm_hour, tm.tm_min, tm.tm_sec);
    2236           0 :                         else if (uptime < ONE_WEEK_SECOND)
    2237           0 :                                 snprintf(time, sizeof(time), "%dd%02dh%02dm",
    2238             :                                          tm.tm_yday, tm.tm_hour, tm.tm_min);
    2239             :                         else
    2240           0 :                                 snprintf(time, sizeof(time), "%02dw%dd%02dh",
    2241             :                                          tm.tm_yday / 7,
    2242           0 :                                          tm.tm_yday - ((tm.tm_yday / 7) * 7),
    2243             :                                          tm.tm_hour);
    2244             : 
    2245           0 :                         vty_out(vty, "   status: %u\n", re->status);
    2246           0 :                         vty_out(vty, "   nexthop_num: %u\n",
    2247           0 :                                 nexthop_group_nexthop_num(&(re->nhe->nhg)));
    2248           0 :                         vty_out(vty, "   nexthop_active_num: %u\n",
    2249           0 :                                 nexthop_group_active_nexthop_num(
    2250           0 :                                         &(re->nhe->nhg)));
    2251           0 :                         vty_out(vty, "   table: %u\n", re->table);
    2252           0 :                         vty_out(vty, "   uptime: %s\n", time);
    2253             : 
    2254           0 :                         for (ALL_NEXTHOPS_PTR(&(re->nhe->nhg), nexthop)) {
    2255           0 :                                 nexthop_num++;
    2256           0 :                                 show_ip_route_nht_dump(vty, nexthop, re,
    2257             :                                                        nexthop_num);
    2258             :                         }
    2259             : 
    2260           0 :                         nexthop_num = 0;
    2261           0 :                         vty_out(vty, "\n");
    2262             :                 }
    2263             :         }
    2264           0 : }
    2265             : 
    2266           0 : static void vty_show_ip_route_summary(struct vty *vty,
    2267             :                                       struct route_table *table, bool use_json)
    2268             : {
    2269           0 :         struct route_node *rn;
    2270           0 :         struct route_entry *re;
    2271             : #define ZEBRA_ROUTE_IBGP  ZEBRA_ROUTE_MAX
    2272             : #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
    2273           0 :         uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
    2274           0 :         uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
    2275           0 :         uint32_t offload_cnt[ZEBRA_ROUTE_TOTAL + 1];
    2276           0 :         uint32_t trap_cnt[ZEBRA_ROUTE_TOTAL + 1];
    2277           0 :         uint32_t i;
    2278           0 :         uint32_t is_ibgp;
    2279           0 :         json_object *json_route_summary = NULL;
    2280           0 :         json_object *json_route_routes = NULL;
    2281             : 
    2282           0 :         memset(&rib_cnt, 0, sizeof(rib_cnt));
    2283           0 :         memset(&fib_cnt, 0, sizeof(fib_cnt));
    2284           0 :         memset(&offload_cnt, 0, sizeof(offload_cnt));
    2285           0 :         memset(&trap_cnt, 0, sizeof(trap_cnt));
    2286             : 
    2287           0 :         if (use_json) {
    2288           0 :                 json_route_summary = json_object_new_object();
    2289           0 :                 json_route_routes = json_object_new_array();
    2290           0 :                 json_object_object_add(json_route_summary, "routes",
    2291             :                                        json_route_routes);
    2292             :         }
    2293             : 
    2294           0 :         for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
    2295           0 :                 RNODE_FOREACH_RE (rn, re) {
    2296           0 :                         is_ibgp = (re->type == ZEBRA_ROUTE_BGP
    2297           0 :                                    && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
    2298             : 
    2299           0 :                         rib_cnt[ZEBRA_ROUTE_TOTAL]++;
    2300           0 :                         if (is_ibgp)
    2301           0 :                                 rib_cnt[ZEBRA_ROUTE_IBGP]++;
    2302             :                         else
    2303           0 :                                 rib_cnt[re->type]++;
    2304             : 
    2305           0 :                         if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
    2306           0 :                                 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
    2307             : 
    2308           0 :                                 if (is_ibgp)
    2309           0 :                                         fib_cnt[ZEBRA_ROUTE_IBGP]++;
    2310             :                                 else
    2311           0 :                                         fib_cnt[re->type]++;
    2312             :                         }
    2313             : 
    2314           0 :                         if (CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED)) {
    2315           0 :                                 if (is_ibgp)
    2316           0 :                                         trap_cnt[ZEBRA_ROUTE_IBGP]++;
    2317             :                                 else
    2318           0 :                                         trap_cnt[re->type]++;
    2319             :                         }
    2320             : 
    2321           0 :                         if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED)) {
    2322           0 :                                 if (is_ibgp)
    2323           0 :                                         offload_cnt[ZEBRA_ROUTE_IBGP]++;
    2324             :                                 else
    2325           0 :                                         offload_cnt[re->type]++;
    2326             :                         }
    2327             :                 }
    2328             : 
    2329           0 :         if (!use_json)
    2330           0 :                 vty_out(vty, "%-20s %-20s %s  (vrf %s)\n", "Route Source",
    2331             :                         "Routes", "FIB",
    2332             :                         zvrf_name(((struct rib_table_info *)
    2333           0 :                                            route_table_get_info(table))
    2334             :                                           ->zvrf));
    2335             : 
    2336           0 :         for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
    2337           0 :                 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
    2338           0 :                                          && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
    2339           0 :                         if (i == ZEBRA_ROUTE_BGP) {
    2340           0 :                                 if (use_json) {
    2341           0 :                                         json_object *json_route_ebgp =
    2342           0 :                                                 json_object_new_object();
    2343             : 
    2344           0 :                                         json_object_int_add(
    2345             :                                                 json_route_ebgp, "fib",
    2346           0 :                                                 fib_cnt[ZEBRA_ROUTE_BGP]);
    2347           0 :                                         json_object_int_add(
    2348             :                                                 json_route_ebgp, "rib",
    2349           0 :                                                 rib_cnt[ZEBRA_ROUTE_BGP]);
    2350           0 :                                         json_object_int_add(
    2351             :                                                 json_route_ebgp, "fibOffLoaded",
    2352           0 :                                                 offload_cnt[ZEBRA_ROUTE_BGP]);
    2353           0 :                                         json_object_int_add(
    2354             :                                                 json_route_ebgp, "fibTrapped",
    2355           0 :                                                 trap_cnt[ZEBRA_ROUTE_BGP]);
    2356             : 
    2357           0 :                                         json_object_string_add(json_route_ebgp,
    2358             :                                                                "type", "ebgp");
    2359           0 :                                         json_object_array_add(json_route_routes,
    2360             :                                                               json_route_ebgp);
    2361             : 
    2362           0 :                                         json_object *json_route_ibgp =
    2363           0 :                                                 json_object_new_object();
    2364             : 
    2365           0 :                                         json_object_int_add(
    2366             :                                                 json_route_ibgp, "fib",
    2367           0 :                                                 fib_cnt[ZEBRA_ROUTE_IBGP]);
    2368           0 :                                         json_object_int_add(
    2369             :                                                 json_route_ibgp, "rib",
    2370           0 :                                                 rib_cnt[ZEBRA_ROUTE_IBGP]);
    2371           0 :                                         json_object_int_add(
    2372             :                                                 json_route_ibgp, "fibOffLoaded",
    2373           0 :                                                 offload_cnt[ZEBRA_ROUTE_IBGP]);
    2374           0 :                                         json_object_int_add(
    2375             :                                                 json_route_ibgp, "fibTrapped",
    2376           0 :                                                 trap_cnt[ZEBRA_ROUTE_IBGP]);
    2377           0 :                                         json_object_string_add(json_route_ibgp,
    2378             :                                                                "type", "ibgp");
    2379           0 :                                         json_object_array_add(json_route_routes,
    2380             :                                                               json_route_ibgp);
    2381             :                                 } else {
    2382           0 :                                         vty_out(vty, "%-20s %-20d %-20d \n",
    2383             :                                                 "ebgp",
    2384             :                                                 rib_cnt[ZEBRA_ROUTE_BGP],
    2385             :                                                 fib_cnt[ZEBRA_ROUTE_BGP]);
    2386           0 :                                         vty_out(vty, "%-20s %-20d %-20d \n",
    2387             :                                                 "ibgp",
    2388             :                                                 rib_cnt[ZEBRA_ROUTE_IBGP],
    2389             :                                                 fib_cnt[ZEBRA_ROUTE_IBGP]);
    2390             :                                 }
    2391             :                         } else {
    2392           0 :                                 if (use_json) {
    2393           0 :                                         json_object *json_route_type =
    2394           0 :                                                 json_object_new_object();
    2395             : 
    2396           0 :                                         json_object_int_add(json_route_type,
    2397           0 :                                                             "fib", fib_cnt[i]);
    2398           0 :                                         json_object_int_add(json_route_type,
    2399             :                                                             "rib", rib_cnt[i]);
    2400             : 
    2401           0 :                                         json_object_int_add(json_route_type,
    2402             :                                                             "fibOffLoaded",
    2403           0 :                                                             offload_cnt[i]);
    2404           0 :                                         json_object_int_add(json_route_type,
    2405             :                                                             "fibTrapped",
    2406           0 :                                                             trap_cnt[i]);
    2407           0 :                                         json_object_string_add(
    2408             :                                                 json_route_type, "type",
    2409             :                                                 zebra_route_string(i));
    2410           0 :                                         json_object_array_add(json_route_routes,
    2411             :                                                               json_route_type);
    2412             :                                 } else
    2413           0 :                                         vty_out(vty, "%-20s %-20d %-20d \n",
    2414             :                                                 zebra_route_string(i),
    2415             :                                                 rib_cnt[i], fib_cnt[i]);
    2416             :                         }
    2417             :                 }
    2418             :         }
    2419             : 
    2420           0 :         if (use_json) {
    2421           0 :                 json_object_int_add(json_route_summary, "routesTotal",
    2422           0 :                                     rib_cnt[ZEBRA_ROUTE_TOTAL]);
    2423           0 :                 json_object_int_add(json_route_summary, "routesTotalFib",
    2424           0 :                                     fib_cnt[ZEBRA_ROUTE_TOTAL]);
    2425             : 
    2426           0 :                 vty_json(vty, json_route_summary);
    2427             :         } else {
    2428           0 :                 vty_out(vty, "------\n");
    2429           0 :                 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
    2430             :                         rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
    2431           0 :                 vty_out(vty, "\n");
    2432             :         }
    2433           0 : }
    2434             : 
    2435             : /*
    2436             :  * Implementation of the ip route summary prefix command.
    2437             :  *
    2438             :  * This command prints the primary prefixes that have been installed by various
    2439             :  * protocols on the box.
    2440             :  *
    2441             :  */
    2442           0 : static void vty_show_ip_route_summary_prefix(struct vty *vty,
    2443             :                                              struct route_table *table,
    2444             :                                              bool use_json)
    2445             : {
    2446           0 :         struct route_node *rn;
    2447           0 :         struct route_entry *re;
    2448           0 :         struct nexthop *nexthop;
    2449             : #define ZEBRA_ROUTE_IBGP  ZEBRA_ROUTE_MAX
    2450             : #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
    2451           0 :         uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
    2452           0 :         uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
    2453           0 :         uint32_t i;
    2454           0 :         int cnt;
    2455           0 :         json_object *json_route_summary = NULL;
    2456           0 :         json_object *json_route_routes = NULL;
    2457             : 
    2458           0 :         memset(&rib_cnt, 0, sizeof(rib_cnt));
    2459           0 :         memset(&fib_cnt, 0, sizeof(fib_cnt));
    2460             : 
    2461           0 :         if (use_json) {
    2462           0 :                 json_route_summary = json_object_new_object();
    2463           0 :                 json_route_routes = json_object_new_array();
    2464           0 :                 json_object_object_add(json_route_summary, "prefixRoutes",
    2465             :                                        json_route_routes);
    2466             :         }
    2467             : 
    2468           0 :         for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
    2469           0 :                 RNODE_FOREACH_RE (rn, re) {
    2470             : 
    2471             :                         /*
    2472             :                          * In case of ECMP, count only once.
    2473             :                          */
    2474           0 :                         cnt = 0;
    2475           0 :                         if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
    2476           0 :                                 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
    2477           0 :                                 fib_cnt[re->type]++;
    2478             :                         }
    2479           0 :                         for (nexthop = re->nhe->nhg.nexthop; (!cnt && nexthop);
    2480           0 :                              nexthop = nexthop->next) {
    2481           0 :                                 cnt++;
    2482           0 :                                 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
    2483           0 :                                 rib_cnt[re->type]++;
    2484           0 :                                 if (re->type == ZEBRA_ROUTE_BGP
    2485           0 :                                     && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
    2486           0 :                                         rib_cnt[ZEBRA_ROUTE_IBGP]++;
    2487           0 :                                         if (CHECK_FLAG(re->status,
    2488             :                                                        ROUTE_ENTRY_INSTALLED))
    2489           0 :                                                 fib_cnt[ZEBRA_ROUTE_IBGP]++;
    2490             :                                 }
    2491             :                         }
    2492             :                 }
    2493             : 
    2494           0 :         if (!use_json)
    2495           0 :                 vty_out(vty, "%-20s %-20s %s  (vrf %s)\n", "Route Source",
    2496             :                         "Prefix Routes", "FIB",
    2497             :                         zvrf_name(((struct rib_table_info *)
    2498           0 :                                            route_table_get_info(table))
    2499             :                                           ->zvrf));
    2500             : 
    2501           0 :         for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
    2502           0 :                 if (rib_cnt[i] > 0) {
    2503           0 :                         if (i == ZEBRA_ROUTE_BGP) {
    2504           0 :                                 if (use_json) {
    2505           0 :                                         json_object *json_route_ebgp =
    2506           0 :                                                 json_object_new_object();
    2507             : 
    2508           0 :                                         json_object_int_add(
    2509             :                                                 json_route_ebgp, "fib",
    2510           0 :                                                 fib_cnt[ZEBRA_ROUTE_BGP]
    2511           0 :                                                         - fib_cnt[ZEBRA_ROUTE_IBGP]);
    2512           0 :                                         json_object_int_add(
    2513             :                                                 json_route_ebgp, "rib",
    2514           0 :                                                 rib_cnt[ZEBRA_ROUTE_BGP]
    2515           0 :                                                         - rib_cnt[ZEBRA_ROUTE_IBGP]);
    2516           0 :                                         json_object_string_add(json_route_ebgp,
    2517             :                                                                "type", "ebgp");
    2518           0 :                                         json_object_array_add(json_route_routes,
    2519             :                                                               json_route_ebgp);
    2520             : 
    2521           0 :                                         json_object *json_route_ibgp =
    2522           0 :                                                 json_object_new_object();
    2523             : 
    2524           0 :                                         json_object_int_add(
    2525             :                                                 json_route_ibgp, "fib",
    2526             :                                                 fib_cnt[ZEBRA_ROUTE_IBGP]);
    2527           0 :                                         json_object_int_add(
    2528             :                                                 json_route_ibgp, "rib",
    2529             :                                                 rib_cnt[ZEBRA_ROUTE_IBGP]);
    2530           0 :                                         json_object_string_add(json_route_ibgp,
    2531             :                                                                "type", "ibgp");
    2532           0 :                                         json_object_array_add(json_route_routes,
    2533             :                                                               json_route_ibgp);
    2534             :                                 } else {
    2535           0 :                                         vty_out(vty, "%-20s %-20d %-20d \n",
    2536             :                                                 "ebgp",
    2537           0 :                                                 rib_cnt[ZEBRA_ROUTE_BGP]
    2538           0 :                                                         - rib_cnt[ZEBRA_ROUTE_IBGP],
    2539           0 :                                                 fib_cnt[ZEBRA_ROUTE_BGP]
    2540           0 :                                                         - fib_cnt[ZEBRA_ROUTE_IBGP]);
    2541           0 :                                         vty_out(vty, "%-20s %-20d %-20d \n",
    2542             :                                                 "ibgp",
    2543             :                                                 rib_cnt[ZEBRA_ROUTE_IBGP],
    2544             :                                                 fib_cnt[ZEBRA_ROUTE_IBGP]);
    2545             :                                 }
    2546             :                         } else {
    2547           0 :                                 if (use_json) {
    2548           0 :                                         json_object *json_route_type =
    2549           0 :                                                 json_object_new_object();
    2550             : 
    2551           0 :                                         json_object_int_add(json_route_type,
    2552           0 :                                                             "fib", fib_cnt[i]);
    2553           0 :                                         json_object_int_add(json_route_type,
    2554             :                                                             "rib", rib_cnt[i]);
    2555           0 :                                         json_object_string_add(
    2556             :                                                 json_route_type, "type",
    2557             :                                                 zebra_route_string(i));
    2558           0 :                                         json_object_array_add(json_route_routes,
    2559             :                                                               json_route_type);
    2560             :                                 } else
    2561           0 :                                         vty_out(vty, "%-20s %-20d %-20d \n",
    2562             :                                                 zebra_route_string(i),
    2563             :                                                 rib_cnt[i], fib_cnt[i]);
    2564             :                         }
    2565             :                 }
    2566             :         }
    2567             : 
    2568           0 :         if (use_json) {
    2569           0 :                 json_object_int_add(json_route_summary, "prefixRoutesTotal",
    2570           0 :                                     rib_cnt[ZEBRA_ROUTE_TOTAL]);
    2571           0 :                 json_object_int_add(json_route_summary, "prefixRoutesTotalFib",
    2572           0 :                                     fib_cnt[ZEBRA_ROUTE_TOTAL]);
    2573             : 
    2574           0 :                 vty_json(vty, json_route_summary);
    2575             :         } else {
    2576           0 :                 vty_out(vty, "------\n");
    2577           0 :                 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
    2578             :                         rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
    2579           0 :                 vty_out(vty, "\n");
    2580             :         }
    2581           0 : }
    2582             : 
    2583           0 : DEFUN (allow_external_route_update,
    2584             :        allow_external_route_update_cmd,
    2585             :        "allow-external-route-update",
    2586             :        "Allow FRR routes to be overwritten by external processes\n")
    2587             : {
    2588           0 :         zrouter.allow_delete = true;
    2589             : 
    2590           0 :         return CMD_SUCCESS;
    2591             : }
    2592             : 
    2593           0 : DEFUN (no_allow_external_route_update,
    2594             :        no_allow_external_route_update_cmd,
    2595             :        "no allow-external-route-update",
    2596             :        NO_STR
    2597             :        "Allow FRR routes to be overwritten by external processes\n")
    2598             : {
    2599           0 :         zrouter.allow_delete = false;
    2600             : 
    2601           0 :         return CMD_SUCCESS;
    2602             : }
    2603             : 
    2604             : /* show vrf */
    2605           0 : DEFUN (show_vrf,
    2606             :        show_vrf_cmd,
    2607             :        "show vrf",
    2608             :        SHOW_STR
    2609             :        "VRF\n")
    2610             : {
    2611           0 :         struct vrf *vrf;
    2612           0 :         struct zebra_vrf *zvrf;
    2613             : 
    2614           0 :         if (vrf_is_backend_netns())
    2615           0 :                 vty_out(vty, "netns-based vrfs\n");
    2616             : 
    2617           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    2618           0 :                 if (!(zvrf = vrf->info))
    2619           0 :                         continue;
    2620           0 :                 if (zvrf_id(zvrf) == VRF_DEFAULT)
    2621           0 :                         continue;
    2622             : 
    2623           0 :                 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
    2624           0 :                 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
    2625           0 :                         vty_out(vty, "inactive");
    2626           0 :                 else if (zvrf_ns_name(zvrf))
    2627           0 :                         vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
    2628             :                                 zvrf_ns_name(zvrf));
    2629             :                 else
    2630           0 :                         vty_out(vty, "id %u table %u", zvrf_id(zvrf),
    2631             :                                 zvrf->table_id);
    2632           0 :                 if (vrf_is_user_cfged(vrf))
    2633           0 :                         vty_out(vty, " (configured)");
    2634           0 :                 vty_out(vty, "\n");
    2635             :         }
    2636             : 
    2637           0 :         return CMD_SUCCESS;
    2638             : }
    2639             : 
    2640           0 : DEFPY (evpn_mh_mac_holdtime,
    2641             :        evpn_mh_mac_holdtime_cmd,
    2642             :        "[no$no] evpn mh mac-holdtime (0-86400)$duration",
    2643             :        NO_STR
    2644             :        "EVPN\n"
    2645             :        "Multihoming\n"
    2646             :        "MAC hold time\n"
    2647             :        "Duration in seconds\n")
    2648             : {
    2649           0 :         return zebra_evpn_mh_mac_holdtime_update(vty, duration,
    2650             :                         no ? true : false);
    2651             : }
    2652             : 
    2653           0 : DEFPY (evpn_mh_neigh_holdtime,
    2654             :        evpn_mh_neigh_holdtime_cmd,
    2655             :        "[no$no] evpn mh neigh-holdtime (0-86400)$duration",
    2656             :        NO_STR
    2657             :        "EVPN\n"
    2658             :        "Multihoming\n"
    2659             :        "Neighbor entry hold time\n"
    2660             :        "Duration in seconds\n")
    2661             : {
    2662             : 
    2663           0 :         return zebra_evpn_mh_neigh_holdtime_update(vty, duration,
    2664             :                                                    no ? true : false);
    2665             : }
    2666             : 
    2667           0 : DEFPY (evpn_mh_startup_delay,
    2668             :        evpn_mh_startup_delay_cmd,
    2669             :        "[no] evpn mh startup-delay(0-3600)$duration",
    2670             :        NO_STR
    2671             :        "EVPN\n"
    2672             :        "Multihoming\n"
    2673             :        "Startup delay\n"
    2674             :        "duration in seconds\n")
    2675             : {
    2676             : 
    2677           0 :         return zebra_evpn_mh_startup_delay_update(vty, duration,
    2678             :                         no ? true : false);
    2679             : }
    2680             : 
    2681           0 : DEFPY(evpn_mh_redirect_off, evpn_mh_redirect_off_cmd,
    2682             :       "[no$no] evpn mh redirect-off",
    2683             :       NO_STR
    2684             :       "EVPN\n"
    2685             :       "Multihoming\n"
    2686             :       "ES bond redirect for fast-failover off\n")
    2687             : {
    2688           0 :         bool redirect_off;
    2689             : 
    2690           0 :         redirect_off = no ? false : true;
    2691             : 
    2692           0 :         return zebra_evpn_mh_redirect_off(vty, redirect_off);
    2693             : }
    2694             : 
    2695           0 : DEFUN (default_vrf_vni_mapping,
    2696             :        default_vrf_vni_mapping_cmd,
    2697             :        "vni " CMD_VNI_RANGE "[prefix-routes-only]",
    2698             :        "VNI corresponding to the DEFAULT VRF\n"
    2699             :        "VNI-ID\n"
    2700             :        "Prefix routes only \n")
    2701             : {
    2702           0 :         char xpath[XPATH_MAXLEN];
    2703           0 :         struct zebra_vrf *zvrf = NULL;
    2704           0 :         int filter = 0;
    2705             : 
    2706           0 :         zvrf = vrf_info_lookup(VRF_DEFAULT);
    2707           0 :         if (!zvrf)
    2708             :                 return CMD_WARNING;
    2709             : 
    2710           0 :         if (argc == 3)
    2711           0 :                 filter = 1;
    2712             : 
    2713           0 :         snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra",
    2714             :                  VRF_DEFAULT_NAME);
    2715           0 :         nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
    2716             : 
    2717           0 :         snprintf(xpath, sizeof(xpath),
    2718             :                  FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id",
    2719             :                  VRF_DEFAULT_NAME);
    2720           0 :         nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[1]->arg);
    2721             : 
    2722           0 :         if (filter) {
    2723           0 :                 snprintf(xpath, sizeof(xpath),
    2724             :                          FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only",
    2725             :                          VRF_DEFAULT_NAME);
    2726           0 :                 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "true");
    2727             :         }
    2728             : 
    2729           0 :         return nb_cli_apply_changes(vty, NULL);
    2730             : }
    2731             : 
    2732           0 : DEFUN (no_default_vrf_vni_mapping,
    2733             :        no_default_vrf_vni_mapping_cmd,
    2734             :        "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
    2735             :        NO_STR
    2736             :        "VNI corresponding to DEFAULT VRF\n"
    2737             :        "VNI-ID\n"
    2738             :        "Prefix routes only \n")
    2739             : {
    2740           0 :         char xpath[XPATH_MAXLEN];
    2741           0 :         int filter = 0;
    2742           0 :         vni_t vni = strtoul(argv[2]->arg, NULL, 10);
    2743           0 :         struct zebra_vrf *zvrf = NULL;
    2744             : 
    2745           0 :         zvrf = vrf_info_lookup(VRF_DEFAULT);
    2746           0 :         if (!zvrf)
    2747             :                 return CMD_WARNING;
    2748             : 
    2749           0 :         if (argc == 4)
    2750           0 :                 filter = 1;
    2751             : 
    2752           0 :         if (zvrf->l3vni != vni) {
    2753           0 :                 vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni,
    2754           0 :                         zvrf->vrf->name);
    2755           0 :                 return CMD_WARNING;
    2756             :         }
    2757             : 
    2758           0 :         snprintf(xpath, sizeof(xpath),
    2759             :                  FRR_VRF_KEY_XPATH "/frr-zebra:zebra/l3vni-id",
    2760             :                  VRF_DEFAULT_NAME);
    2761           0 :         nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, argv[2]->arg);
    2762             : 
    2763           0 :         if (filter) {
    2764           0 :                 snprintf(xpath, sizeof(xpath),
    2765             :                          FRR_VRF_KEY_XPATH "/frr-zebra:zebra/prefix-only",
    2766             :                          VRF_DEFAULT_NAME);
    2767           0 :                 nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, "true");
    2768             :         }
    2769             : 
    2770           0 :         snprintf(xpath, sizeof(xpath), FRR_VRF_KEY_XPATH "/frr-zebra:zebra",
    2771             :                  VRF_DEFAULT_NAME);
    2772           0 :         nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
    2773             : 
    2774           0 :         return nb_cli_apply_changes(vty, NULL);
    2775             : }
    2776             : 
    2777           0 : DEFUN (vrf_vni_mapping,
    2778             :        vrf_vni_mapping_cmd,
    2779             :        "vni " CMD_VNI_RANGE "[prefix-routes-only]",
    2780             :        "VNI corresponding to tenant VRF\n"
    2781             :        "VNI-ID\n"
    2782             :        "prefix-routes-only\n")
    2783             : {
    2784           0 :         int filter = 0;
    2785             : 
    2786           0 :         ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
    2787             : 
    2788           0 :         assert(vrf);
    2789           0 :         assert(zvrf);
    2790             : 
    2791           0 :         if (argc == 3)
    2792           0 :                 filter = 1;
    2793             : 
    2794           0 :         nb_cli_enqueue_change(vty, "./frr-zebra:zebra", NB_OP_CREATE, NULL);
    2795           0 :         nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_MODIFY,
    2796           0 :                               argv[1]->arg);
    2797             : 
    2798           0 :         if (filter)
    2799           0 :                 nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only",
    2800             :                                       NB_OP_MODIFY, "true");
    2801             : 
    2802           0 :         return nb_cli_apply_changes(vty, NULL);
    2803             : }
    2804             : 
    2805           0 : DEFUN (no_vrf_vni_mapping,
    2806             :        no_vrf_vni_mapping_cmd,
    2807             :        "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
    2808             :        NO_STR
    2809             :        "VNI corresponding to tenant VRF\n"
    2810             :        "VNI-ID\n"
    2811             :        "prefix-routes-only\n")
    2812             : {
    2813           0 :         int filter = 0;
    2814             : 
    2815           0 :         ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
    2816           0 :         vni_t vni = strtoul(argv[2]->arg, NULL, 10);
    2817             : 
    2818           0 :         assert(vrf);
    2819           0 :         assert(zvrf);
    2820             : 
    2821           0 :         if (argc == 4)
    2822           0 :                 filter = 1;
    2823             : 
    2824           0 :         if (zvrf->l3vni != vni) {
    2825           0 :                 vty_out(vty, "VNI %d doesn't exist in VRF: %s \n", vni,
    2826           0 :                         zvrf->vrf->name);
    2827           0 :                 return CMD_WARNING;
    2828             :         }
    2829             : 
    2830           0 :         nb_cli_enqueue_change(vty, "./frr-zebra:zebra/l3vni-id", NB_OP_DESTROY,
    2831           0 :                               argv[2]->arg);
    2832             : 
    2833           0 :         if (filter)
    2834           0 :                 nb_cli_enqueue_change(vty, "./frr-zebra:zebra/prefix-only",
    2835             :                                       NB_OP_DESTROY, "true");
    2836             : 
    2837           0 :         nb_cli_enqueue_change(vty, "./frr-zebra:zebra", NB_OP_DESTROY, NULL);
    2838             : 
    2839           0 :         return nb_cli_apply_changes(vty, NULL);
    2840             : }
    2841             : 
    2842             : /* show vrf */
    2843           0 : DEFPY (show_vrf_vni,
    2844             :        show_vrf_vni_cmd,
    2845             :        "show vrf [<NAME$vrf_name|all$vrf_all>] vni [json]",
    2846             :        SHOW_STR
    2847             :        VRF_FULL_CMD_HELP_STR
    2848             :        "VNI\n"
    2849             :        JSON_STR)
    2850             : {
    2851           0 :         struct vrf *vrf;
    2852           0 :         struct zebra_vrf *zvrf;
    2853           0 :         json_object *json = NULL;
    2854           0 :         json_object *json_vrfs = NULL;
    2855           0 :         bool uj = use_json(argc, argv);
    2856           0 :         bool use_vrf = false;
    2857             : 
    2858           0 :         if (uj)
    2859           0 :                 json = json_object_new_object();
    2860             : 
    2861             :         /* show vrf vni used to display across all vrfs
    2862             :          * This is enhanced to support only for specific
    2863             :          * vrf based output.
    2864             :          */
    2865           0 :         if (vrf_all || !vrf_name) {
    2866           0 :                 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    2867           0 :                         zvrf = vrf->info;
    2868           0 :                         if (!zvrf)
    2869           0 :                                 continue;
    2870             : 
    2871             :                         use_vrf = true;
    2872             :                         break;
    2873             :                 }
    2874           0 :                 if (use_vrf) {
    2875           0 :                         if (!uj)
    2876           0 :                                 vty_out(vty,
    2877             :                                         "%-37s %-10s %-20s %-20s %-5s %-18s\n",
    2878             :                                         "VRF", "VNI", "VxLAN IF", "L3-SVI",
    2879             :                                         "State", "Rmac");
    2880             :                         else
    2881           0 :                                 json_vrfs = json_object_new_array();
    2882             :                 } else {
    2883           0 :                         if (uj)
    2884           0 :                                 vty_json(vty, json);
    2885             :                         else
    2886           0 :                                 vty_out(vty, "%% VRF does not exist\n");
    2887             : 
    2888           0 :                         return CMD_WARNING;
    2889             :                 }
    2890             :         }
    2891             : 
    2892           0 :         if (use_vrf) {
    2893           0 :                 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    2894           0 :                         zvrf = vrf->info;
    2895           0 :                         if (!zvrf)
    2896           0 :                                 continue;
    2897             : 
    2898           0 :                         zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
    2899             :                 }
    2900           0 :         } else if (vrf_name) {
    2901           0 :                 zvrf = zebra_vrf_lookup_by_name(vrf_name);
    2902           0 :                 if (!zvrf) {
    2903           0 :                         if (uj)
    2904           0 :                                 vty_json(vty, json);
    2905             :                         else
    2906           0 :                                 vty_out(vty,
    2907             :                                         "%% VRF '%s' specified does not exist\n",
    2908             :                                         vrf_name);
    2909             : 
    2910           0 :                         return CMD_WARNING;
    2911             :                 }
    2912             : 
    2913           0 :                 if (!uj)
    2914           0 :                         vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n",
    2915             :                                 "VRF", "VNI", "VxLAN IF", "L3-SVI", "State",
    2916             :                                 "Rmac");
    2917             :                 else
    2918           0 :                         json_vrfs = json_object_new_array();
    2919             : 
    2920           0 :                 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
    2921             :         }
    2922             : 
    2923           0 :         if (uj) {
    2924           0 :                 json_object_object_add(json, "vrfs", json_vrfs);
    2925           0 :                 vty_json(vty, json);
    2926             :         }
    2927             : 
    2928             :         return CMD_SUCCESS;
    2929             : }
    2930             : 
    2931           0 : DEFUN (show_evpn_global,
    2932             :        show_evpn_global_cmd,
    2933             :        "show evpn [json]",
    2934             :        SHOW_STR
    2935             :        "EVPN\n"
    2936             :        JSON_STR)
    2937             : {
    2938           0 :         bool uj = use_json(argc, argv);
    2939             : 
    2940           0 :         zebra_vxlan_print_evpn(vty, uj);
    2941           0 :         return CMD_SUCCESS;
    2942             : }
    2943             : 
    2944           0 : DEFPY(show_evpn_neigh, show_neigh_cmd, "show ip neigh",
    2945             :       SHOW_STR IP_STR "neighbors\n")
    2946             : 
    2947             : {
    2948           0 :         zebra_neigh_show(vty);
    2949             : 
    2950           0 :         return CMD_SUCCESS;
    2951             : }
    2952             : 
    2953           0 : DEFPY(show_evpn_l2_nh,
    2954             :       show_evpn_l2_nh_cmd,
    2955             :       "show evpn l2-nh [json$json]",
    2956             :       SHOW_STR
    2957             :       "EVPN\n"
    2958             :       "Layer2 nexthops\n"
    2959             :       JSON_STR)
    2960             : {
    2961           0 :         bool uj = !!json;
    2962             : 
    2963           0 :         zebra_evpn_l2_nh_show(vty, uj);
    2964             : 
    2965           0 :         return CMD_SUCCESS;
    2966             : }
    2967             : 
    2968           0 : DEFPY(show_evpn_es,
    2969             :       show_evpn_es_cmd,
    2970             :       "show evpn es [NAME$esi_str|detail$detail] [json$json]",
    2971             :       SHOW_STR
    2972             :       "EVPN\n"
    2973             :       "Ethernet Segment\n"
    2974             :       "ES ID\n"
    2975             :       "Detailed information\n"
    2976             :       JSON_STR)
    2977             : {
    2978           0 :         esi_t esi;
    2979           0 :         bool uj = !!json;
    2980             : 
    2981           0 :         if (esi_str) {
    2982           0 :                 if (!str_to_esi(esi_str, &esi)) {
    2983           0 :                         vty_out(vty, "%% Malformed ESI\n");
    2984           0 :                         return CMD_WARNING;
    2985             :                 }
    2986           0 :                 zebra_evpn_es_show_esi(vty, uj, &esi);
    2987             :         } else {
    2988           0 :                 if (detail)
    2989           0 :                         zebra_evpn_es_show_detail(vty, uj);
    2990             :                 else
    2991           0 :                         zebra_evpn_es_show(vty, uj);
    2992             :         }
    2993             : 
    2994             :         return CMD_SUCCESS;
    2995             : }
    2996             : 
    2997           0 : DEFPY(show_evpn_es_evi,
    2998             :       show_evpn_es_evi_cmd,
    2999             :       "show evpn es-evi [vni (1-16777215)$vni] [detail$detail] [json$json]",
    3000             :       SHOW_STR
    3001             :       "EVPN\n"
    3002             :       "Ethernet Segment per EVI\n"
    3003             :       "VxLAN Network Identifier\n"
    3004             :       "VNI\n"
    3005             :       "Detailed information\n"
    3006             :       JSON_STR)
    3007             : {
    3008           0 :         bool uj = !!json;
    3009           0 :         bool ud = !!detail;
    3010             : 
    3011           0 :         if (vni)
    3012           0 :                 zebra_evpn_es_evi_show_vni(vty, uj, vni, ud);
    3013             :         else
    3014           0 :                 zebra_evpn_es_evi_show(vty, uj, ud);
    3015             : 
    3016           0 :         return CMD_SUCCESS;
    3017             : }
    3018             : 
    3019           0 : DEFPY(show_evpn_access_vlan,
    3020             :       show_evpn_access_vlan_cmd,
    3021             :       "show evpn access-vlan [(1-4094)$vid | detail$detail] [json$json]",
    3022             :       SHOW_STR
    3023             :       "EVPN\n"
    3024             :       "Access VLANs\n"
    3025             :       "VLAN ID\n"
    3026             :       "Detailed information\n"
    3027             :       JSON_STR)
    3028             : {
    3029           0 :         bool uj = !!json;
    3030             : 
    3031           0 :         if (vid) {
    3032           0 :                 zebra_evpn_acc_vl_show_vid(vty, uj, vid);
    3033             :         } else {
    3034           0 :                 if (detail)
    3035           0 :                         zebra_evpn_acc_vl_show_detail(vty, uj);
    3036             :                 else
    3037           0 :                         zebra_evpn_acc_vl_show(vty, uj);
    3038             :         }
    3039             : 
    3040           0 :         return CMD_SUCCESS;
    3041             : }
    3042             : 
    3043           0 : DEFUN (show_evpn_vni,
    3044             :        show_evpn_vni_cmd,
    3045             :        "show evpn vni [json]",
    3046             :        SHOW_STR
    3047             :        "EVPN\n"
    3048             :        "VxLAN Network Identifier\n"
    3049             :        JSON_STR)
    3050             : {
    3051           0 :         struct zebra_vrf *zvrf;
    3052           0 :         bool uj = use_json(argc, argv);
    3053             : 
    3054           0 :         zvrf = zebra_vrf_get_evpn();
    3055           0 :         zebra_vxlan_print_vnis(vty, zvrf, uj);
    3056           0 :         return CMD_SUCCESS;
    3057             : }
    3058             : 
    3059           0 : DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
    3060             :        "show evpn vni detail [json]",
    3061             :        SHOW_STR
    3062             :        "EVPN\n"
    3063             :        "VxLAN Network Identifier\n"
    3064             :        "Detailed Information On Each VNI\n"
    3065             :        JSON_STR)
    3066             : {
    3067           0 :         struct zebra_vrf *zvrf;
    3068           0 :         bool uj = use_json(argc, argv);
    3069             : 
    3070           0 :         zvrf = zebra_vrf_get_evpn();
    3071           0 :         zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
    3072           0 :         return CMD_SUCCESS;
    3073             : }
    3074             : 
    3075           0 : DEFUN (show_evpn_vni_vni,
    3076             :        show_evpn_vni_vni_cmd,
    3077             :        "show evpn vni " CMD_VNI_RANGE "[json]",
    3078             :        SHOW_STR
    3079             :        "EVPN\n"
    3080             :        "VxLAN Network Identifier\n"
    3081             :        "VNI number\n"
    3082             :        JSON_STR)
    3083             : {
    3084           0 :         struct zebra_vrf *zvrf;
    3085           0 :         vni_t vni;
    3086           0 :         bool uj = use_json(argc, argv);
    3087             : 
    3088           0 :         vni = strtoul(argv[3]->arg, NULL, 10);
    3089           0 :         zvrf = zebra_vrf_get_evpn();
    3090           0 :         zebra_vxlan_print_vni(vty, zvrf, vni, uj, NULL);
    3091           0 :         return CMD_SUCCESS;
    3092             : }
    3093             : 
    3094           0 : DEFUN (show_evpn_rmac_vni_mac,
    3095             :        show_evpn_rmac_vni_mac_cmd,
    3096             :        "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
    3097             :        SHOW_STR
    3098             :        "EVPN\n"
    3099             :        "RMAC\n"
    3100             :        "L3 VNI\n"
    3101             :        "VNI number\n"
    3102             :        "MAC\n"
    3103             :        "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
    3104             :        JSON_STR)
    3105             : {
    3106           0 :         vni_t l3vni = 0;
    3107           0 :         struct ethaddr mac;
    3108           0 :         bool uj = use_json(argc, argv);
    3109             : 
    3110           0 :         l3vni = strtoul(argv[4]->arg, NULL, 10);
    3111           0 :         if (!prefix_str2mac(argv[6]->arg, &mac)) {
    3112           0 :                 vty_out(vty, "%% Malformed MAC address\n");
    3113           0 :                 return CMD_WARNING;
    3114             :         }
    3115           0 :         zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
    3116           0 :         return CMD_SUCCESS;
    3117             : }
    3118             : 
    3119           0 : DEFUN (show_evpn_rmac_vni,
    3120             :        show_evpn_rmac_vni_cmd,
    3121             :        "show evpn rmac vni " CMD_VNI_RANGE "[json]",
    3122             :        SHOW_STR
    3123             :        "EVPN\n"
    3124             :        "RMAC\n"
    3125             :        "L3 VNI\n"
    3126             :        "VNI number\n"
    3127             :        JSON_STR)
    3128             : {
    3129           0 :         vni_t l3vni = 0;
    3130           0 :         bool uj = use_json(argc, argv);
    3131             : 
    3132           0 :         l3vni = strtoul(argv[4]->arg, NULL, 10);
    3133           0 :         zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
    3134             : 
    3135           0 :         return CMD_SUCCESS;
    3136             : }
    3137             : 
    3138           0 : DEFUN (show_evpn_rmac_vni_all,
    3139             :        show_evpn_rmac_vni_all_cmd,
    3140             :        "show evpn rmac vni all [json]",
    3141             :        SHOW_STR
    3142             :        "EVPN\n"
    3143             :        "RMAC addresses\n"
    3144             :        "L3 VNI\n"
    3145             :        "All VNIs\n"
    3146             :        JSON_STR)
    3147             : {
    3148           0 :         bool uj = use_json(argc, argv);
    3149             : 
    3150           0 :         zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
    3151             : 
    3152           0 :         return CMD_SUCCESS;
    3153             : }
    3154             : 
    3155           0 : DEFUN (show_evpn_nh_vni_ip,
    3156             :        show_evpn_nh_vni_ip_cmd,
    3157             :        "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
    3158             :        SHOW_STR
    3159             :        "EVPN\n"
    3160             :        "Remote Vteps\n"
    3161             :        "L3 VNI\n"
    3162             :        "VNI number\n"
    3163             :        "Ip address\n"
    3164             :        "Host address (ipv4 or ipv6)\n"
    3165             :        JSON_STR)
    3166             : {
    3167           0 :         vni_t l3vni;
    3168           0 :         struct ipaddr ip;
    3169           0 :         bool uj = use_json(argc, argv);
    3170             : 
    3171           0 :         l3vni = strtoul(argv[4]->arg, NULL, 10);
    3172           0 :         if (str2ipaddr(argv[6]->arg, &ip) != 0) {
    3173           0 :                 if (!uj)
    3174           0 :                         vty_out(vty, "%% Malformed Neighbor address\n");
    3175           0 :                 return CMD_WARNING;
    3176             :         }
    3177           0 :         zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
    3178             : 
    3179           0 :         return CMD_SUCCESS;
    3180             : }
    3181             : 
    3182           0 : DEFUN (show_evpn_nh_vni,
    3183             :        show_evpn_nh_vni_cmd,
    3184             :        "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
    3185             :        SHOW_STR
    3186             :        "EVPN\n"
    3187             :        "Remote Vteps\n"
    3188             :        "L3 VNI\n"
    3189             :        "VNI number\n"
    3190             :        JSON_STR)
    3191             : {
    3192           0 :         vni_t l3vni;
    3193           0 :         bool uj = use_json(argc, argv);
    3194             : 
    3195           0 :         l3vni = strtoul(argv[4]->arg, NULL, 10);
    3196           0 :         zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
    3197             : 
    3198           0 :         return CMD_SUCCESS;
    3199             : }
    3200             : 
    3201           0 : DEFUN (show_evpn_nh_vni_all,
    3202             :        show_evpn_nh_vni_all_cmd,
    3203             :        "show evpn next-hops vni all [json]",
    3204             :        SHOW_STR
    3205             :        "EVPN\n"
    3206             :        "Remote VTEPs\n"
    3207             :        "L3 VNI\n"
    3208             :        "All VNIs\n"
    3209             :        JSON_STR)
    3210             : {
    3211           0 :         bool uj = use_json(argc, argv);
    3212             : 
    3213           0 :         zebra_vxlan_print_nh_all_l3vni(vty, uj);
    3214             : 
    3215           0 :         return CMD_SUCCESS;
    3216             : }
    3217             : 
    3218           0 : DEFUN (show_evpn_mac_vni,
    3219             :        show_evpn_mac_vni_cmd,
    3220             :        "show evpn mac vni " CMD_VNI_RANGE "[json]",
    3221             :        SHOW_STR
    3222             :        "EVPN\n"
    3223             :        "MAC addresses\n"
    3224             :        "VxLAN Network Identifier\n"
    3225             :        "VNI number\n"
    3226             :        JSON_STR)
    3227             : {
    3228           0 :         struct zebra_vrf *zvrf;
    3229           0 :         vni_t vni;
    3230           0 :         bool uj = use_json(argc, argv);
    3231             : 
    3232           0 :         vni = strtoul(argv[4]->arg, NULL, 10);
    3233           0 :         zvrf = zebra_vrf_get_evpn();
    3234           0 :         zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj, false);
    3235           0 :         return CMD_SUCCESS;
    3236             : }
    3237             : 
    3238           0 : DEFPY (show_evpn_mac_vni_detail,
    3239             :        show_evpn_mac_vni_detail_cmd,
    3240             :        "show evpn mac vni " CMD_VNI_RANGE " detail [json]",
    3241             :        SHOW_STR
    3242             :        "EVPN\n"
    3243             :        "MAC addresses\n"
    3244             :        "VXLAN Network Identifier\n"
    3245             :        "VNI number\n"
    3246             :        "Detailed Information On Each VNI MAC\n"
    3247             :        JSON_STR)
    3248             : {
    3249           0 :         struct zebra_vrf *zvrf;
    3250           0 :         bool uj = use_json(argc, argv);
    3251             : 
    3252           0 :         zvrf = zebra_vrf_get_evpn();
    3253           0 :         zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj, true);
    3254           0 :         return CMD_SUCCESS;
    3255             : }
    3256             : 
    3257           0 : DEFUN (show_evpn_mac_vni_all,
    3258             :        show_evpn_mac_vni_all_cmd,
    3259             :        "show evpn mac vni all [json]",
    3260             :        SHOW_STR
    3261             :        "EVPN\n"
    3262             :        "MAC addresses\n"
    3263             :        "VxLAN Network Identifier\n"
    3264             :        "All VNIs\n"
    3265             :        JSON_STR)
    3266             : {
    3267           0 :         struct zebra_vrf *zvrf;
    3268           0 :         bool uj = use_json(argc, argv);
    3269             : 
    3270           0 :         zvrf = zebra_vrf_get_evpn();
    3271           0 :         zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
    3272           0 :         return CMD_SUCCESS;
    3273             : }
    3274             : 
    3275           0 : DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
    3276             :        "show evpn mac vni all detail [json]",
    3277             :        SHOW_STR
    3278             :        "EVPN\n"
    3279             :        "MAC addresses\n"
    3280             :        "VxLAN Network Identifier\n"
    3281             :        "All VNIs\n"
    3282             :        "Detailed Information On Each VNI MAC\n"
    3283             :        JSON_STR)
    3284             : {
    3285           0 :         struct zebra_vrf *zvrf;
    3286           0 :         bool uj = use_json(argc, argv);
    3287             : 
    3288           0 :         zvrf = zebra_vrf_get_evpn();
    3289           0 :         zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
    3290           0 :         return CMD_SUCCESS;
    3291             : }
    3292             : 
    3293           0 : DEFUN (show_evpn_mac_vni_all_vtep,
    3294             :        show_evpn_mac_vni_all_vtep_cmd,
    3295             :        "show evpn mac vni all vtep A.B.C.D [json]",
    3296             :        SHOW_STR
    3297             :        "EVPN\n"
    3298             :        "MAC addresses\n"
    3299             :        "VxLAN Network Identifier\n"
    3300             :        "All VNIs\n"
    3301             :        "Remote VTEP\n"
    3302             :        "Remote VTEP IP address\n"
    3303             :        JSON_STR)
    3304             : {
    3305           0 :         struct zebra_vrf *zvrf;
    3306           0 :         struct in_addr vtep_ip;
    3307           0 :         bool uj = use_json(argc, argv);
    3308             : 
    3309           0 :         if (!inet_aton(argv[6]->arg, &vtep_ip)) {
    3310           0 :                 if (!uj)
    3311           0 :                         vty_out(vty, "%% Malformed VTEP IP address\n");
    3312           0 :                 return CMD_WARNING;
    3313             :         }
    3314           0 :         zvrf = zebra_vrf_get_evpn();
    3315           0 :         zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
    3316             : 
    3317           0 :         return CMD_SUCCESS;
    3318             : }
    3319             : 
    3320             : 
    3321           0 : DEFUN (show_evpn_mac_vni_mac,
    3322             :        show_evpn_mac_vni_mac_cmd,
    3323             :        "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
    3324             :        SHOW_STR
    3325             :        "EVPN\n"
    3326             :        "MAC addresses\n"
    3327             :        "VxLAN Network Identifier\n"
    3328             :        "VNI number\n"
    3329             :        "MAC\n"
    3330             :        "MAC address (e.g., 00:e0:ec:20:12:62)\n"
    3331             :        JSON_STR)
    3332             : 
    3333             : {
    3334           0 :         struct zebra_vrf *zvrf;
    3335           0 :         vni_t vni;
    3336           0 :         struct ethaddr mac;
    3337           0 :         bool uj = use_json(argc, argv);
    3338             : 
    3339           0 :         vni = strtoul(argv[4]->arg, NULL, 10);
    3340           0 :         if (!prefix_str2mac(argv[6]->arg, &mac)) {
    3341           0 :                 vty_out(vty, "%% Malformed MAC address\n");
    3342           0 :                 return CMD_WARNING;
    3343             :         }
    3344           0 :         zvrf = zebra_vrf_get_evpn();
    3345           0 :         zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
    3346           0 :         return CMD_SUCCESS;
    3347             : }
    3348             : 
    3349           0 : DEFUN (show_evpn_mac_vni_vtep,
    3350             :        show_evpn_mac_vni_vtep_cmd,
    3351             :        "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
    3352             :        SHOW_STR
    3353             :        "EVPN\n"
    3354             :        "MAC addresses\n"
    3355             :        "VxLAN Network Identifier\n"
    3356             :        "VNI number\n"
    3357             :        "Remote VTEP\n"
    3358             :        "Remote VTEP IP address\n"
    3359             :        JSON_STR)
    3360             : {
    3361           0 :         struct zebra_vrf *zvrf;
    3362           0 :         vni_t vni;
    3363           0 :         struct in_addr vtep_ip;
    3364           0 :         bool uj = use_json(argc, argv);
    3365             : 
    3366           0 :         vni = strtoul(argv[4]->arg, NULL, 10);
    3367           0 :         if (!inet_aton(argv[6]->arg, &vtep_ip)) {
    3368           0 :                 if (!uj)
    3369           0 :                         vty_out(vty, "%% Malformed VTEP IP address\n");
    3370           0 :                 return CMD_WARNING;
    3371             :         }
    3372             : 
    3373           0 :         zvrf = zebra_vrf_get_evpn();
    3374           0 :         zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
    3375           0 :         return CMD_SUCCESS;
    3376             : }
    3377             : 
    3378           0 : DEFPY (show_evpn_mac_vni_all_dad,
    3379             :        show_evpn_mac_vni_all_dad_cmd,
    3380             :        "show evpn mac vni all duplicate [json]",
    3381             :        SHOW_STR
    3382             :        "EVPN\n"
    3383             :        "MAC addresses\n"
    3384             :        "VxLAN Network Identifier\n"
    3385             :        "All VNIs\n"
    3386             :        "Duplicate address list\n"
    3387             :        JSON_STR)
    3388             : {
    3389           0 :         struct zebra_vrf *zvrf;
    3390           0 :         bool uj = use_json(argc, argv);
    3391             : 
    3392           0 :         zvrf = zebra_vrf_get_evpn();
    3393           0 :         zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
    3394           0 :         return CMD_SUCCESS;
    3395             : }
    3396             : 
    3397             : 
    3398           0 : DEFPY (show_evpn_mac_vni_dad,
    3399             :        show_evpn_mac_vni_dad_cmd,
    3400             :        "show evpn mac vni " CMD_VNI_RANGE " duplicate [json]",
    3401             :        SHOW_STR
    3402             :        "EVPN\n"
    3403             :        "MAC addresses\n"
    3404             :        "VxLAN Network Identifier\n"
    3405             :        "VNI number\n"
    3406             :        "Duplicate address list\n"
    3407             :        JSON_STR)
    3408             : {
    3409           0 :         struct zebra_vrf *zvrf;
    3410           0 :         bool uj = use_json(argc, argv);
    3411             : 
    3412           0 :         zvrf = zebra_vrf_get_evpn();
    3413             : 
    3414           0 :         zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
    3415             : 
    3416           0 :         return CMD_SUCCESS;
    3417             : }
    3418             : 
    3419           0 : DEFPY (show_evpn_neigh_vni_dad,
    3420             :        show_evpn_neigh_vni_dad_cmd,
    3421             :        "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate [json]",
    3422             :        SHOW_STR
    3423             :        "EVPN\n"
    3424             :        "ARP and ND cache\n"
    3425             :        "VxLAN Network Identifier\n"
    3426             :        "VNI number\n"
    3427             :        "Duplicate address list\n"
    3428             :        JSON_STR)
    3429             : {
    3430           0 :         struct zebra_vrf *zvrf;
    3431           0 :         bool uj = use_json(argc, argv);
    3432             : 
    3433           0 :         zvrf = zebra_vrf_get_evpn();
    3434           0 :         zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
    3435           0 :         return CMD_SUCCESS;
    3436             : }
    3437             : 
    3438           0 : DEFPY (show_evpn_neigh_vni_all_dad,
    3439             :        show_evpn_neigh_vni_all_dad_cmd,
    3440             :        "show evpn arp-cache vni all duplicate [json]",
    3441             :        SHOW_STR
    3442             :        "EVPN\n"
    3443             :        "ARP and ND cache\n"
    3444             :        "VxLAN Network Identifier\n"
    3445             :        "All VNIs\n"
    3446             :        "Duplicate address list\n"
    3447             :        JSON_STR)
    3448             : {
    3449           0 :         struct zebra_vrf *zvrf;
    3450           0 :         bool uj = use_json(argc, argv);
    3451             : 
    3452           0 :         zvrf = zebra_vrf_get_evpn();
    3453           0 :         zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
    3454           0 :         return CMD_SUCCESS;
    3455             : }
    3456             : 
    3457             : 
    3458           0 : DEFUN (show_evpn_neigh_vni,
    3459             :        show_evpn_neigh_vni_cmd,
    3460             :        "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
    3461             :        SHOW_STR
    3462             :        "EVPN\n"
    3463             :        "ARP and ND cache\n"
    3464             :        "VxLAN Network Identifier\n"
    3465             :        "VNI number\n"
    3466             :        JSON_STR)
    3467             : {
    3468           0 :         struct zebra_vrf *zvrf;
    3469           0 :         vni_t vni;
    3470           0 :         bool uj = use_json(argc, argv);
    3471             : 
    3472           0 :         vni = strtoul(argv[4]->arg, NULL, 10);
    3473           0 :         zvrf = zebra_vrf_get_evpn();
    3474           0 :         zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
    3475           0 :         return CMD_SUCCESS;
    3476             : }
    3477             : 
    3478           0 : DEFUN (show_evpn_neigh_vni_all,
    3479             :        show_evpn_neigh_vni_all_cmd,
    3480             :        "show evpn arp-cache vni all [json]",
    3481             :        SHOW_STR
    3482             :        "EVPN\n"
    3483             :        "ARP and ND cache\n"
    3484             :        "VxLAN Network Identifier\n"
    3485             :        "All VNIs\n"
    3486             :        JSON_STR)
    3487             : {
    3488           0 :         struct zebra_vrf *zvrf;
    3489           0 :         bool uj = use_json(argc, argv);
    3490             : 
    3491           0 :         zvrf = zebra_vrf_get_evpn();
    3492           0 :         zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
    3493           0 :         return CMD_SUCCESS;
    3494             : }
    3495             : 
    3496           0 : DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
    3497             :        "show evpn arp-cache vni all detail [json]",
    3498             :        SHOW_STR
    3499             :        "EVPN\n"
    3500             :        "ARP and ND cache\n"
    3501             :        "VxLAN Network Identifier\n"
    3502             :        "All VNIs\n"
    3503             :        "Neighbor details for all vnis in detail\n" JSON_STR)
    3504             : {
    3505           0 :         struct zebra_vrf *zvrf;
    3506           0 :         bool uj = use_json(argc, argv);
    3507             : 
    3508           0 :         zvrf = zebra_vrf_get_evpn();
    3509           0 :         zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
    3510           0 :         return CMD_SUCCESS;
    3511             : }
    3512             : 
    3513           0 : DEFUN (show_evpn_neigh_vni_neigh,
    3514             :        show_evpn_neigh_vni_neigh_cmd,
    3515             :        "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
    3516             :        SHOW_STR
    3517             :        "EVPN\n"
    3518             :        "ARP and ND cache\n"
    3519             :        "VxLAN Network Identifier\n"
    3520             :        "VNI number\n"
    3521             :        "Neighbor\n"
    3522             :        "Neighbor address (IPv4 or IPv6 address)\n"
    3523             :        JSON_STR)
    3524             : {
    3525           0 :         struct zebra_vrf *zvrf;
    3526           0 :         vni_t vni;
    3527           0 :         struct ipaddr ip;
    3528           0 :         bool uj = use_json(argc, argv);
    3529             : 
    3530           0 :         vni = strtoul(argv[4]->arg, NULL, 10);
    3531           0 :         if (str2ipaddr(argv[6]->arg, &ip) != 0) {
    3532           0 :                 if (!uj)
    3533           0 :                         vty_out(vty, "%% Malformed Neighbor address\n");
    3534           0 :                 return CMD_WARNING;
    3535             :         }
    3536           0 :         zvrf = zebra_vrf_get_evpn();
    3537           0 :         zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
    3538           0 :         return CMD_SUCCESS;
    3539             : }
    3540             : 
    3541           0 : DEFUN (show_evpn_neigh_vni_vtep,
    3542             :        show_evpn_neigh_vni_vtep_cmd,
    3543             :        "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
    3544             :        SHOW_STR
    3545             :        "EVPN\n"
    3546             :        "ARP and ND cache\n"
    3547             :        "VxLAN Network Identifier\n"
    3548             :        "VNI number\n"
    3549             :        "Remote VTEP\n"
    3550             :        "Remote VTEP IP address\n"
    3551             :        JSON_STR)
    3552             : {
    3553           0 :         struct zebra_vrf *zvrf;
    3554           0 :         vni_t vni;
    3555           0 :         struct in_addr vtep_ip;
    3556           0 :         bool uj = use_json(argc, argv);
    3557             : 
    3558           0 :         vni = strtoul(argv[4]->arg, NULL, 10);
    3559           0 :         if (!inet_aton(argv[6]->arg, &vtep_ip)) {
    3560           0 :                 if (!uj)
    3561           0 :                         vty_out(vty, "%% Malformed VTEP IP address\n");
    3562           0 :                 return CMD_WARNING;
    3563             :         }
    3564             : 
    3565           0 :         zvrf = zebra_vrf_get_evpn();
    3566           0 :         zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
    3567           0 :         return CMD_SUCCESS;
    3568             : }
    3569             : 
    3570             : /* policy routing contexts */
    3571           0 : DEFUN (show_pbr_ipset,
    3572             :        show_pbr_ipset_cmd,
    3573             :        "show pbr ipset [WORD]",
    3574             :        SHOW_STR
    3575             :        "Policy-Based Routing\n"
    3576             :        "IPset Context information\n"
    3577             :        "IPset Name information\n")
    3578             : {
    3579           0 :         int idx = 0;
    3580           0 :         int found = 0;
    3581           0 :         found = argv_find(argv, argc, "WORD", &idx);
    3582           0 :         if (!found)
    3583           0 :                 zebra_pbr_show_ipset_list(vty, NULL);
    3584             :         else
    3585           0 :                 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
    3586           0 :         return CMD_SUCCESS;
    3587             : }
    3588             : 
    3589             : /* policy routing contexts */
    3590           0 : DEFUN (show_pbr_iptable,
    3591             :        show_pbr_iptable_cmd,
    3592             :        "show pbr iptable [WORD]",
    3593             :        SHOW_STR
    3594             :        "Policy-Based Routing\n"
    3595             :        "IPtable Context information\n"
    3596             :        "IPtable Name information\n")
    3597             : {
    3598           0 :         int idx = 0;
    3599           0 :         int found = 0;
    3600             : 
    3601           0 :         found = argv_find(argv, argc, "WORD", &idx);
    3602           0 :         if (!found)
    3603           0 :                 zebra_pbr_show_iptable(vty, NULL);
    3604             :         else
    3605           0 :                 zebra_pbr_show_iptable(vty, argv[idx]->arg);
    3606           0 :         return CMD_SUCCESS;
    3607             : }
    3608             : 
    3609             : /* policy routing contexts */
    3610           0 : DEFPY (show_pbr_rule,
    3611             :        show_pbr_rule_cmd,
    3612             :        "show pbr rule",
    3613             :        SHOW_STR
    3614             :        "Policy-Based Routing\n"
    3615             :        "Rule\n")
    3616             : {
    3617           0 :         zebra_pbr_show_rule(vty);
    3618           0 :         return CMD_SUCCESS;
    3619             : }
    3620             : 
    3621           0 : DEFPY (pbr_nexthop_resolve,
    3622             :        pbr_nexthop_resolve_cmd,
    3623             :        "[no$no] pbr nexthop-resolve",
    3624             :        NO_STR
    3625             :        "Policy Based Routing\n"
    3626             :        "Resolve nexthop for dataplane programming\n")
    3627             : {
    3628           0 :         zebra_pbr_expand_action_update(!no);
    3629           0 :         return CMD_SUCCESS;
    3630             : }
    3631             : 
    3632           0 : DEFPY (clear_evpn_dup_addr,
    3633             :        clear_evpn_dup_addr_cmd,
    3634             :        "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE"$vni [mac X:X:X:X:X:X | ip <A.B.C.D|X:X::X:X>]>",
    3635             :        CLEAR_STR
    3636             :        "EVPN\n"
    3637             :        "Duplicate address \n"
    3638             :        "VxLAN Network Identifier\n"
    3639             :        "VNI number\n"
    3640             :        "All VNIs\n"
    3641             :        "MAC\n"
    3642             :        "MAC address (e.g., 00:e0:ec:20:12:62)\n"
    3643             :        "IP\n"
    3644             :        "IPv4 address\n"
    3645             :        "IPv6 address\n")
    3646             : {
    3647           0 :         struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
    3648           0 :         int ret = CMD_SUCCESS;
    3649           0 :         struct list *input;
    3650           0 :         struct yang_data *yang_dup = NULL, *yang_dup_ip = NULL,
    3651           0 :                          *yang_dup_mac = NULL;
    3652             : 
    3653           0 :         input = list_new();
    3654             : 
    3655           0 :         if (!vni_str) {
    3656           0 :                 yang_dup = yang_data_new(
    3657             :                         "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice",
    3658             :                         "all-case");
    3659             :         } else {
    3660           0 :                 yang_dup = yang_data_new_uint32(
    3661             :                         "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id",
    3662             :                         vni);
    3663           0 :                 if (!is_zero_mac(&mac->eth_addr)) {
    3664           0 :                         yang_dup_mac = yang_data_new_mac(
    3665             :                                 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/mac-addr",
    3666             :                                 &mac->eth_addr);
    3667           0 :                         if (yang_dup_mac)
    3668           0 :                                 listnode_add(input, yang_dup_mac);
    3669           0 :                 } else if (ip) {
    3670           0 :                         if (sockunion_family(ip) == AF_INET) {
    3671           0 :                                 host_ip.ipa_type = IPADDR_V4;
    3672           0 :                                 host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
    3673             :                         } else {
    3674           0 :                                 host_ip.ipa_type = IPADDR_V6;
    3675           0 :                                 memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
    3676             :                                        sizeof(struct in6_addr));
    3677             :                         }
    3678             : 
    3679           0 :                         yang_dup_ip = yang_data_new_ip(
    3680             :                                 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/vni-ipaddr",
    3681             :                                 &host_ip);
    3682             : 
    3683           0 :                         if (yang_dup_ip)
    3684           0 :                                 listnode_add(input, yang_dup_ip);
    3685             :                 }
    3686             :         }
    3687             : 
    3688           0 :         if (yang_dup) {
    3689           0 :                 listnode_add(input, yang_dup);
    3690           0 :                 ret = nb_cli_rpc(vty, "/frr-zebra:clear-evpn-dup-addr", input,
    3691             :                                  NULL);
    3692             :         }
    3693             : 
    3694           0 :         list_delete(&input);
    3695             : 
    3696           0 :         return ret;
    3697             : }
    3698             : 
    3699           0 : DEFPY_HIDDEN (evpn_accept_bgp_seq,
    3700             :               evpn_accept_bgp_seq_cmd,
    3701             :               "evpn accept-bgp-seq",
    3702             :               "EVPN\n"
    3703             :               "Accept all sequence numbers from BGP\n")
    3704             : {
    3705           0 :         zebra_vxlan_set_accept_bgp_seq(true);
    3706           0 :         return CMD_SUCCESS;
    3707             : }
    3708             : 
    3709           0 : DEFPY_HIDDEN (no_evpn_accept_bgp_seq,
    3710             :               no_evpn_accept_bgp_seq_cmd,
    3711             :               "no evpn accept-bgp-seq",
    3712             :               NO_STR
    3713             :               "EVPN\n"
    3714             :               "Accept all sequence numbers from BGP\n")
    3715             : {
    3716           0 :         zebra_vxlan_set_accept_bgp_seq(false);
    3717           0 :         return CMD_SUCCESS;
    3718             : }
    3719             : 
    3720             : /* Static ip route configuration write function. */
    3721           0 : static int zebra_ip_config(struct vty *vty)
    3722             : {
    3723           0 :         int write = 0;
    3724             : 
    3725           0 :         write += zebra_import_table_config(vty, VRF_DEFAULT);
    3726             : 
    3727           0 :         return write;
    3728             : }
    3729             : 
    3730           0 : DEFUN (ip_zebra_import_table_distance,
    3731             :        ip_zebra_import_table_distance_cmd,
    3732             :        "ip import-table (1-252) [distance (1-255)] [route-map RMAP_NAME]",
    3733             :        IP_STR
    3734             :        "import routes from non-main kernel table\n"
    3735             :        "kernel routing table id\n"
    3736             :        "Distance for imported routes\n"
    3737             :        "Default distance value\n"
    3738             :        "route-map for filtering\n"
    3739             :        "route-map name\n")
    3740             : {
    3741           0 :         uint32_t table_id = 0;
    3742             : 
    3743           0 :         table_id = strtoul(argv[2]->arg, NULL, 10);
    3744           0 :         int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
    3745           0 :         char *rmap =
    3746           0 :                 strmatch(argv[argc - 2]->text, "route-map")
    3747           0 :                         ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
    3748           0 :                         : NULL;
    3749           0 :         int ret;
    3750             : 
    3751           0 :         if (argc == 7 || (argc == 5 && !rmap))
    3752           0 :                 distance = strtoul(argv[4]->arg, NULL, 10);
    3753             : 
    3754           0 :         if (!is_zebra_valid_kernel_table(table_id)) {
    3755           0 :                 vty_out(vty,
    3756             :                         "Invalid routing table ID, %d. Must be in range 1-252\n",
    3757             :                         table_id);
    3758           0 :                 if (rmap)
    3759           0 :                         XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
    3760           0 :                 return CMD_WARNING;
    3761             :         }
    3762             : 
    3763           0 :         if (is_zebra_main_routing_table(table_id)) {
    3764           0 :                 vty_out(vty,
    3765             :                         "Invalid routing table ID, %d. Must be non-default table\n",
    3766             :                         table_id);
    3767           0 :                 if (rmap)
    3768           0 :                         XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
    3769           0 :                 return CMD_WARNING;
    3770             :         }
    3771             : 
    3772           0 :         ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id,
    3773             :                                  distance, rmap, 1);
    3774           0 :         if (rmap)
    3775           0 :                 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
    3776             : 
    3777             :         return ret;
    3778             : }
    3779             : 
    3780           0 : DEFUN_HIDDEN (zebra_packet_process,
    3781             :               zebra_packet_process_cmd,
    3782             :               "zebra zapi-packets (1-10000)",
    3783             :               ZEBRA_STR
    3784             :               "Zapi Protocol\n"
    3785             :               "Number of packets to process before relinquishing thread\n")
    3786             : {
    3787           0 :         uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
    3788             : 
    3789           0 :         atomic_store_explicit(&zrouter.packets_to_process, packets,
    3790             :                               memory_order_relaxed);
    3791             : 
    3792           0 :         return CMD_SUCCESS;
    3793             : }
    3794             : 
    3795           0 : DEFUN_HIDDEN (no_zebra_packet_process,
    3796             :               no_zebra_packet_process_cmd,
    3797             :               "no zebra zapi-packets [(1-10000)]",
    3798             :               NO_STR
    3799             :               ZEBRA_STR
    3800             :               "Zapi Protocol\n"
    3801             :               "Number of packets to process before relinquishing thread\n")
    3802             : {
    3803           0 :         atomic_store_explicit(&zrouter.packets_to_process,
    3804             :                               ZEBRA_ZAPI_PACKETS_TO_PROCESS,
    3805             :                               memory_order_relaxed);
    3806             : 
    3807           0 :         return CMD_SUCCESS;
    3808             : }
    3809             : 
    3810           0 : DEFUN_HIDDEN (zebra_workqueue_timer,
    3811             :               zebra_workqueue_timer_cmd,
    3812             :               "zebra work-queue (0-10000)",
    3813             :               ZEBRA_STR
    3814             :               "Work Queue\n"
    3815             :               "Time in milliseconds\n")
    3816             : {
    3817           0 :         uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
    3818           0 :         zrouter.ribq->spec.hold = timer;
    3819             : 
    3820           0 :         return CMD_SUCCESS;
    3821             : }
    3822             : 
    3823           0 : DEFUN_HIDDEN (no_zebra_workqueue_timer,
    3824             :               no_zebra_workqueue_timer_cmd,
    3825             :               "no zebra work-queue [(0-10000)]",
    3826             :               NO_STR
    3827             :               ZEBRA_STR
    3828             :               "Work Queue\n"
    3829             :               "Time in milliseconds\n")
    3830             : {
    3831           0 :         zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
    3832             : 
    3833           0 :         return CMD_SUCCESS;
    3834             : }
    3835             : 
    3836           0 : DEFUN (no_ip_zebra_import_table,
    3837             :        no_ip_zebra_import_table_cmd,
    3838             :        "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
    3839             :        NO_STR
    3840             :        IP_STR
    3841             :        "import routes from non-main kernel table\n"
    3842             :        "kernel routing table id\n"
    3843             :        "Distance for imported routes\n"
    3844             :        "Default distance value\n"
    3845             :        "route-map for filtering\n"
    3846             :        "route-map name\n")
    3847             : {
    3848           0 :         uint32_t table_id = 0;
    3849           0 :         table_id = strtoul(argv[3]->arg, NULL, 10);
    3850             : 
    3851           0 :         if (!is_zebra_valid_kernel_table(table_id)) {
    3852           0 :                 vty_out(vty,
    3853             :                         "Invalid routing table ID. Must be in range 1-252\n");
    3854           0 :                 return CMD_WARNING;
    3855             :         }
    3856             : 
    3857           0 :         if (is_zebra_main_routing_table(table_id)) {
    3858           0 :                 vty_out(vty,
    3859             :                         "Invalid routing table ID, %d. Must be non-default table\n",
    3860             :                         table_id);
    3861           0 :                 return CMD_WARNING;
    3862             :         }
    3863             : 
    3864           0 :         if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id))
    3865             :                 return CMD_SUCCESS;
    3866             : 
    3867           0 :         return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0));
    3868             : }
    3869             : 
    3870           0 : DEFPY (zebra_nexthop_group_keep,
    3871             :        zebra_nexthop_group_keep_cmd,
    3872             :        "[no] zebra nexthop-group keep (1-3600)",
    3873             :        NO_STR
    3874             :        ZEBRA_STR
    3875             :        "Nexthop-Group\n"
    3876             :        "How long to keep\n"
    3877             :        "Time in seconds from 1-3600\n")
    3878             : {
    3879           0 :         if (no)
    3880           0 :                 zrouter.nhg_keep = ZEBRA_DEFAULT_NHG_KEEP_TIMER;
    3881             :         else
    3882           0 :                 zrouter.nhg_keep = keep;
    3883             : 
    3884             :         return CMD_SUCCESS;
    3885             : }
    3886             : 
    3887           0 : static int config_write_protocol(struct vty *vty)
    3888             : {
    3889           0 :         if (zrouter.allow_delete)
    3890           0 :                 vty_out(vty, "allow-external-route-update\n");
    3891             : 
    3892           0 :         if (zrouter.nhg_keep != ZEBRA_DEFAULT_NHG_KEEP_TIMER)
    3893           0 :                 vty_out(vty, "zebra nexthop-group keep %u\n", zrouter.nhg_keep);
    3894             : 
    3895           0 :         if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
    3896           0 :                 vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
    3897             : 
    3898           0 :         if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
    3899           0 :                 vty_out(vty, "zebra zapi-packets %u\n",
    3900           0 :                         zrouter.packets_to_process);
    3901             : 
    3902           0 :         enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
    3903             : 
    3904           0 :         if (ipv4_multicast_mode != MCAST_NO_CONFIG)
    3905           0 :                 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
    3906             :                         ipv4_multicast_mode == MCAST_URIB_ONLY
    3907             :                                 ? "urib-only"
    3908             :                                 : ipv4_multicast_mode == MCAST_MRIB_ONLY
    3909             :                                           ? "mrib-only"
    3910             :                                           : ipv4_multicast_mode
    3911             :                                                             == MCAST_MIX_MRIB_FIRST
    3912             :                                                     ? "mrib-then-urib"
    3913             :                                                     : ipv4_multicast_mode
    3914             :                                                                       == MCAST_MIX_DISTANCE
    3915             :                                                               ? "lower-distance"
    3916             :                                                               : "longer-prefix");
    3917             : 
    3918             :         /* Include dataplane info */
    3919           0 :         dplane_config_write_helper(vty);
    3920             : 
    3921           0 :         zebra_evpn_mh_config_write(vty);
    3922             : 
    3923           0 :         zebra_pbr_config_write(vty);
    3924             : 
    3925           0 :         if (!zebra_vxlan_get_accept_bgp_seq())
    3926           0 :                 vty_out(vty, "no evpn accept-bgp-seq\n");
    3927             : 
    3928             :         /* Include nexthop-group config */
    3929           0 :         if (!zebra_nhg_kernel_nexthops_enabled())
    3930           0 :                 vty_out(vty, "no zebra nexthop kernel enable\n");
    3931             : 
    3932           0 :         if (zebra_nhg_proto_nexthops_only())
    3933           0 :                 vty_out(vty, "zebra nexthop proto only\n");
    3934             : 
    3935           0 :         if (!zebra_nhg_recursive_use_backups())
    3936           0 :                 vty_out(vty, "no zebra nexthop resolve-via-backup\n");
    3937             : 
    3938           0 :         if (rnh_get_hide_backups())
    3939           0 :                 vty_out(vty, "ip nht hide-backup-events\n");
    3940             : 
    3941             : #ifdef HAVE_NETLINK
    3942             :         /* Include netlink info */
    3943           0 :         netlink_config_write_helper(vty);
    3944             : #endif /* HAVE_NETLINK */
    3945             : 
    3946           0 :         return 1;
    3947             : }
    3948             : 
    3949           0 : DEFUN (show_zebra,
    3950             :        show_zebra_cmd,
    3951             :        "show zebra",
    3952             :        SHOW_STR
    3953             :        ZEBRA_STR)
    3954             : {
    3955           0 :         struct vrf *vrf;
    3956           0 :         struct ttable *table = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
    3957           0 :         char *out;
    3958             : 
    3959           0 :         ttable_rowseps(table, 0, BOTTOM, true, '-');
    3960           0 :         ttable_add_row(table, "OS|%s(%s)", cmd_system_get(), cmd_release_get());
    3961           0 :         ttable_add_row(table, "ECMP Maximum|%d", zrouter.multipath_num);
    3962           0 :         ttable_add_row(table, "v4 Forwarding|%s", ipforward() ? "On" : "Off");
    3963           0 :         ttable_add_row(table, "v6 Forwarding|%s",
    3964           0 :                        ipforward_ipv6() ? "On" : "Off");
    3965           0 :         ttable_add_row(table, "MPLS|%s", mpls_enabled ? "On" : "Off");
    3966           0 :         ttable_add_row(table, "EVPN|%s", is_evpn_enabled() ? "On" : "Off");
    3967           0 :         ttable_add_row(table, "Kernel socket buffer size|%d", rcvbufsize);
    3968             : 
    3969             : 
    3970             : #ifdef GNU_LINUX
    3971           0 :         if (!vrf_is_backend_netns())
    3972           0 :                 ttable_add_row(table, "VRF|l3mdev Available");
    3973             :         else
    3974           0 :                 ttable_add_row(table, "VRF|Namespaces");
    3975             : #else
    3976             :         ttable_add_row(table, "VRF|Not Available");
    3977             : #endif
    3978             : 
    3979           0 :         ttable_add_row(table, "ASIC offload|%s",
    3980           0 :                        zrouter.asic_offloaded ? "Used" : "Unavailable");
    3981             : 
    3982             :         /*
    3983             :          * Do not display this unless someone is actually using it
    3984             :          *
    3985             :          * Why this distinction?  I think this is effectively dead code
    3986             :          * and should not be exposed.  Maybe someone proves me wrong.
    3987             :          */
    3988           0 :         if (zrouter.asic_notification_nexthop_control)
    3989           0 :                 ttable_add_row(table, "ASIC offload and nexthop control|Used");
    3990             : 
    3991           0 :         ttable_add_row(table, "RA|%s",
    3992           0 :                        rtadv_compiled_in() ? "Compiled in" : "Not Compiled in");
    3993           0 :         ttable_add_row(table, "RFC 5549|%s",
    3994           0 :                        rtadv_get_interfaces_configured_from_bgp()
    3995             :                                ? "BGP is using"
    3996             :                                : "BGP is not using");
    3997             : 
    3998           0 :         ttable_add_row(table, "Kernel NHG|%s",
    3999           0 :                        zrouter.supports_nhgs ? "Available" : "Unavailable");
    4000             : 
    4001           0 :         ttable_add_row(table, "Allow Non FRR route deletion|%s",
    4002           0 :                        zrouter.allow_delete ? "Yes" : "No");
    4003           0 :         ttable_add_row(table, "v4 All LinkDown Routes|%s",
    4004           0 :                        zrouter.all_linkdownv4 ? "On" : "Off");
    4005           0 :         ttable_add_row(table, "v4 Default LinkDown Routes|%s",
    4006           0 :                        zrouter.default_linkdownv4 ? "On" : "Off");
    4007           0 :         ttable_add_row(table, "v6 All LinkDown Routes|%s",
    4008           0 :                        zrouter.all_linkdownv6 ? "On" : "Off");
    4009           0 :         ttable_add_row(table, "v6 Default LinkDown Routes|%s",
    4010           0 :                        zrouter.default_linkdownv6 ? "On" : "Off");
    4011             : 
    4012           0 :         ttable_add_row(table, "v4 All MC Forwarding|%s",
    4013           0 :                        zrouter.all_mc_forwardingv4 ? "On" : "Off");
    4014           0 :         ttable_add_row(table, "v4 Default MC Forwarding|%s",
    4015           0 :                        zrouter.default_mc_forwardingv4 ? "On" : "Off");
    4016           0 :         ttable_add_row(table, "v6 All MC Forwarding|%s",
    4017           0 :                        zrouter.all_mc_forwardingv6 ? "On" : "Off");
    4018           0 :         ttable_add_row(table, "v6 Default MC Forwarding|%s",
    4019           0 :                        zrouter.default_mc_forwardingv6 ? "On" : "Off");
    4020             : 
    4021           0 :         out = ttable_dump(table, "\n");
    4022           0 :         vty_out(vty, "%s\n", out);
    4023           0 :         XFREE(MTYPE_TMP, out);
    4024             : 
    4025           0 :         ttable_del(table);
    4026           0 :         vty_out(vty,
    4027             :                 "                            Route      Route      Neighbor   LSP        LSP\n");
    4028           0 :         vty_out(vty,
    4029             :                 "VRF                         Installs   Removals    Updates   Installs   Removals\n");
    4030             : 
    4031           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    4032           0 :                 struct zebra_vrf *zvrf = vrf->info;
    4033             : 
    4034           0 :                 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64" %10" PRIu64 " %10" PRIu64 "\n",
    4035           0 :                         vrf->name, zvrf->installs, zvrf->removals,
    4036             :                         zvrf->neigh_updates, zvrf->lsp_installs,
    4037             :                         zvrf->lsp_removals);
    4038             :         }
    4039             : 
    4040           0 :         return CMD_SUCCESS;
    4041             : }
    4042             : 
    4043           8 : DEFUN (ip_forwarding,
    4044             :        ip_forwarding_cmd,
    4045             :        "ip forwarding",
    4046             :        IP_STR
    4047             :        "Turn on IP forwarding\n")
    4048             : {
    4049           8 :         int ret;
    4050             : 
    4051           8 :         ret = ipforward();
    4052           8 :         if (ret == 0)
    4053           0 :                 ret = ipforward_on();
    4054             : 
    4055           0 :         if (ret == 0) {
    4056           0 :                 vty_out(vty, "Can't turn on IP forwarding\n");
    4057           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4058             :         }
    4059             : 
    4060             :         return CMD_SUCCESS;
    4061             : }
    4062             : 
    4063           0 : DEFUN (no_ip_forwarding,
    4064             :        no_ip_forwarding_cmd,
    4065             :        "no ip forwarding",
    4066             :        NO_STR
    4067             :        IP_STR
    4068             :        "Turn off IP forwarding\n")
    4069             : {
    4070           0 :         int ret;
    4071             : 
    4072           0 :         ret = ipforward();
    4073           0 :         if (ret != 0)
    4074           0 :                 ret = ipforward_off();
    4075             : 
    4076           0 :         if (ret != 0) {
    4077           0 :                 vty_out(vty, "Can't turn off IP forwarding\n");
    4078           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4079             :         }
    4080             : 
    4081             :         return CMD_SUCCESS;
    4082             : }
    4083             : 
    4084             : /* Only display ip forwarding is enabled or not. */
    4085           0 : DEFUN (show_ip_forwarding,
    4086             :        show_ip_forwarding_cmd,
    4087             :        "show ip forwarding",
    4088             :        SHOW_STR
    4089             :        IP_STR
    4090             :        "IP forwarding status\n")
    4091             : {
    4092           0 :         int ret;
    4093             : 
    4094           0 :         ret = ipforward();
    4095             : 
    4096           0 :         if (ret == 0)
    4097           0 :                 vty_out(vty, "IP forwarding is off\n");
    4098             :         else
    4099           0 :                 vty_out(vty, "IP forwarding is on\n");
    4100           0 :         return CMD_SUCCESS;
    4101             : }
    4102             : 
    4103             : /* Only display ipv6 forwarding is enabled or not. */
    4104           0 : DEFUN (show_ipv6_forwarding,
    4105             :        show_ipv6_forwarding_cmd,
    4106             :        "show ipv6 forwarding",
    4107             :        SHOW_STR
    4108             :        "IPv6 information\n"
    4109             :        "Forwarding status\n")
    4110             : {
    4111           0 :         int ret;
    4112             : 
    4113           0 :         ret = ipforward_ipv6();
    4114             : 
    4115           0 :         switch (ret) {
    4116           0 :         case -1:
    4117           0 :                 vty_out(vty, "ipv6 forwarding is unknown\n");
    4118           0 :                 break;
    4119           0 :         case 0:
    4120           0 :                 vty_out(vty, "ipv6 forwarding is %s\n", "off");
    4121           0 :                 break;
    4122           0 :         case 1:
    4123           0 :                 vty_out(vty, "ipv6 forwarding is %s\n", "on");
    4124           0 :                 break;
    4125           0 :         default:
    4126           0 :                 vty_out(vty, "ipv6 forwarding is %s\n", "off");
    4127           0 :                 break;
    4128             :         }
    4129           0 :         return CMD_SUCCESS;
    4130             : }
    4131             : 
    4132           8 : DEFUN (ipv6_forwarding,
    4133             :        ipv6_forwarding_cmd,
    4134             :        "ipv6 forwarding",
    4135             :        IPV6_STR
    4136             :        "Turn on IPv6 forwarding\n")
    4137             : {
    4138           8 :         int ret;
    4139             : 
    4140           8 :         ret = ipforward_ipv6();
    4141           8 :         if (ret == 0)
    4142           0 :                 ret = ipforward_ipv6_on();
    4143             : 
    4144           0 :         if (ret == 0) {
    4145           0 :                 vty_out(vty, "Can't turn on IPv6 forwarding\n");
    4146           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4147             :         }
    4148             : 
    4149             :         return CMD_SUCCESS;
    4150             : }
    4151             : 
    4152           0 : DEFUN (no_ipv6_forwarding,
    4153             :        no_ipv6_forwarding_cmd,
    4154             :        "no ipv6 forwarding",
    4155             :        NO_STR
    4156             :        IPV6_STR
    4157             :        "Turn off IPv6 forwarding\n")
    4158             : {
    4159           0 :         int ret;
    4160             : 
    4161           0 :         ret = ipforward_ipv6();
    4162           0 :         if (ret != 0)
    4163           0 :                 ret = ipforward_ipv6_off();
    4164             : 
    4165           0 :         if (ret != 0) {
    4166           0 :                 vty_out(vty, "Can't turn off IPv6 forwarding\n");
    4167           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4168             :         }
    4169             : 
    4170             :         return CMD_SUCCESS;
    4171             : }
    4172             : 
    4173             : /* Display dataplane info */
    4174           0 : DEFUN (show_dataplane,
    4175             :        show_dataplane_cmd,
    4176             :        "show zebra dplane [detailed]",
    4177             :        SHOW_STR
    4178             :        ZEBRA_STR
    4179             :        "Zebra dataplane information\n"
    4180             :        "Detailed output\n")
    4181             : {
    4182           0 :         int idx = 0;
    4183           0 :         bool detailed = false;
    4184             : 
    4185           0 :         if (argv_find(argv, argc, "detailed", &idx))
    4186           0 :                 detailed = true;
    4187             : 
    4188           0 :         return dplane_show_helper(vty, detailed);
    4189             : }
    4190             : 
    4191             : /* Display dataplane providers info */
    4192           0 : DEFUN (show_dataplane_providers,
    4193             :        show_dataplane_providers_cmd,
    4194             :        "show zebra dplane providers [detailed]",
    4195             :        SHOW_STR
    4196             :        ZEBRA_STR
    4197             :        "Zebra dataplane information\n"
    4198             :        "Zebra dataplane provider information\n"
    4199             :        "Detailed output\n")
    4200             : {
    4201           0 :         int idx = 0;
    4202           0 :         bool detailed = false;
    4203             : 
    4204           0 :         if (argv_find(argv, argc, "detailed", &idx))
    4205           0 :                 detailed = true;
    4206             : 
    4207           0 :         return dplane_show_provs_helper(vty, detailed);
    4208             : }
    4209             : 
    4210             : /* Configure dataplane incoming queue limit */
    4211           0 : DEFUN (zebra_dplane_queue_limit,
    4212             :        zebra_dplane_queue_limit_cmd,
    4213             :        "zebra dplane limit (0-10000)",
    4214             :        ZEBRA_STR
    4215             :        "Zebra dataplane\n"
    4216             :        "Limit incoming queued updates\n"
    4217             :        "Number of queued updates\n")
    4218             : {
    4219           0 :         uint32_t limit = 0;
    4220             : 
    4221           0 :         limit = strtoul(argv[3]->arg, NULL, 10);
    4222             : 
    4223           0 :         dplane_set_in_queue_limit(limit, true);
    4224             : 
    4225           0 :         return CMD_SUCCESS;
    4226             : }
    4227             : 
    4228             : /* Reset dataplane queue limit to default value */
    4229           0 : DEFUN (no_zebra_dplane_queue_limit,
    4230             :        no_zebra_dplane_queue_limit_cmd,
    4231             :        "no zebra dplane limit [(0-10000)]",
    4232             :        NO_STR
    4233             :        ZEBRA_STR
    4234             :        "Zebra dataplane\n"
    4235             :        "Limit incoming queued updates\n"
    4236             :        "Number of queued updates\n")
    4237             : {
    4238           0 :         dplane_set_in_queue_limit(0, false);
    4239             : 
    4240           0 :         return CMD_SUCCESS;
    4241             : }
    4242             : 
    4243           0 : DEFUN (zebra_show_routing_tables_summary,
    4244             :        zebra_show_routing_tables_summary_cmd,
    4245             :        "show zebra router table summary",
    4246             :        SHOW_STR
    4247             :        ZEBRA_STR
    4248             :        "The Zebra Router Information\n"
    4249             :        "Table Information about this Zebra Router\n"
    4250             :        "Summary Information\n")
    4251             : {
    4252           0 :         zebra_router_show_table_summary(vty);
    4253             : 
    4254           0 :         return CMD_SUCCESS;
    4255             : }
    4256             : 
    4257             : /* Table configuration write function. */
    4258           0 : static int config_write_table(struct vty *vty)
    4259             : {
    4260           0 :         return 0;
    4261             : }
    4262             : 
    4263             : /* IPForwarding configuration write function. */
    4264           0 : static int config_write_forwarding(struct vty *vty)
    4265             : {
    4266           0 :         if (!ipforward())
    4267           0 :                 vty_out(vty, "no ip forwarding\n");
    4268           0 :         if (!ipforward_ipv6())
    4269           0 :                 vty_out(vty, "no ipv6 forwarding\n");
    4270           0 :         vty_out(vty, "!\n");
    4271           0 :         return 0;
    4272             : }
    4273             : 
    4274           0 : DEFUN_HIDDEN (show_frr,
    4275             :               show_frr_cmd,
    4276             :               "show frr",
    4277             :               SHOW_STR
    4278             :               "FRR\n")
    4279             : {
    4280           0 :         vty_out(vty, "........ .. .  .. . ..... ...77:................................................\n");
    4281           0 :         vty_out(vty, ".............................7777:..............................................\n");
    4282           0 :         vty_out(vty, ".............................777777,............................................\n");
    4283           0 :         vty_out(vty, "... .........................77777777,..........................................\n");
    4284           0 :         vty_out(vty, "............................=7777777777:........................................\n");
    4285           0 :         vty_out(vty, "........................:7777777777777777,......................................\n");
    4286           0 :         vty_out(vty, ".................... ~7777777777777?~,..........................................\n");
    4287           0 :         vty_out(vty, "...................I7777777777+.................................................\n");
    4288           0 :         vty_out(vty, "................,777777777?............  .......................................\n");
    4289           0 :         vty_out(vty, "..............:77777777?..........~?77777.......................................\n");
    4290           0 :         vty_out(vty, ".............77777777~........=7777777777.......................................\n");
    4291           0 :         vty_out(vty, ".......... +7777777,.......?7777777777777.......................................\n");
    4292           0 :         vty_out(vty, "..........7777777~......:7777777777777777......77?,.............................\n");
    4293           0 :         vty_out(vty, "........:777777?......+777777777777777777......777777I,.........................\n");
    4294           0 :         vty_out(vty, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
    4295           0 :         vty_out(vty, "......?777777......7777777777777777777777......,?777777777?.....................\n");
    4296           0 :         vty_out(vty, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
    4297           0 :         vty_out(vty, "....+77777+.....I77777777777777777:...................+777777I..................\n");
    4298           0 :         vty_out(vty, "...~77777+.....7777777777777777=........................?777777......    .......\n");
    4299           0 :         vty_out(vty, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
    4300           0 :         vty_out(vty, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
    4301           0 :         vty_out(vty, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
    4302           0 :         vty_out(vty, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
    4303           0 :         vty_out(vty, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
    4304           0 :         vty_out(vty, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
    4305           0 :         vty_out(vty, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
    4306           0 :         vty_out(vty, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
    4307           0 :         vty_out(vty, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
    4308           0 :         vty_out(vty, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
    4309           0 :         vty_out(vty, "..........77777777777I.....I7777777777777....................7777777777:........\n");
    4310           0 :         vty_out(vty, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
    4311           0 :         vty_out(vty, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
    4312           0 :         vty_out(vty, "..........777777777777......7777777777777..................77777777777777777,...\n");
    4313           0 :         vty_out(vty, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
    4314           0 :         vty_out(vty, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
    4315           0 :         vty_out(vty, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
    4316           0 :         vty_out(vty, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
    4317           0 :         vty_out(vty, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
    4318           0 :         vty_out(vty, ".............77777777777777........?77777......777777777?......=7777=...........\n");
    4319           0 :         vty_out(vty, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
    4320           0 :         vty_out(vty, "..............~777777777777777~................777777......:77777=..............\n");
    4321           0 :         vty_out(vty, "...............:7777777777777777?..............:777777,.....=77=................\n");
    4322           0 :         vty_out(vty, "................,777777777777777777?,...........,777777:.....,..................\n");
    4323           0 :         vty_out(vty, "........... ......I777777777777777777777I.........777777~.......................\n");
    4324           0 :         vty_out(vty, "...................,777777777777777777777..........777777+......................\n");
    4325           0 :         vty_out(vty, ".....................+7777777777777777777...........777777?.....................\n");
    4326           0 :         vty_out(vty, ".......................=77777777777777777............777777I....................\n");
    4327           0 :         vty_out(vty, ".........................:777777777777777.............I77777I...................\n");
    4328           0 :         vty_out(vty, "............................~777777777777..............+777777..................\n");
    4329           0 :         vty_out(vty, "................................~77777777...............=777777.................\n");
    4330           0 :         vty_out(vty, ".....................................:=?I................~777777................\n");
    4331           0 :         vty_out(vty, "..........................................................:777777,..............\n");
    4332           0 :         vty_out(vty, ".... ... ... .  . .... ....... ....... ....................:777777..............\n");
    4333             : 
    4334           0 :         return CMD_SUCCESS;
    4335             : }
    4336             : 
    4337             : #ifdef HAVE_NETLINK
    4338           0 : DEFUN_HIDDEN(zebra_kernel_netlink_batch_tx_buf,
    4339             :              zebra_kernel_netlink_batch_tx_buf_cmd,
    4340             :              "zebra kernel netlink batch-tx-buf (1-1048576) (1-1048576)",
    4341             :              ZEBRA_STR
    4342             :              "Zebra kernel interface\n"
    4343             :              "Set Netlink parameters\n"
    4344             :              "Set batch buffer size and send threshold\n"
    4345             :              "Size of the buffer\n"
    4346             :              "Send threshold\n")
    4347             : {
    4348           0 :         uint32_t bufsize = 0, threshold = 0;
    4349             : 
    4350           0 :         bufsize = strtoul(argv[4]->arg, NULL, 10);
    4351           0 :         threshold = strtoul(argv[5]->arg, NULL, 10);
    4352             : 
    4353           0 :         netlink_set_batch_buffer_size(bufsize, threshold, true);
    4354             : 
    4355           0 :         return CMD_SUCCESS;
    4356             : }
    4357             : 
    4358           0 : DEFUN_HIDDEN(no_zebra_kernel_netlink_batch_tx_buf,
    4359             :              no_zebra_kernel_netlink_batch_tx_buf_cmd,
    4360             :              "no zebra kernel netlink batch-tx-buf [(0-1048576)] [(0-1048576)]",
    4361             :              NO_STR ZEBRA_STR
    4362             :              "Zebra kernel interface\n"
    4363             :              "Set Netlink parameters\n"
    4364             :              "Set batch buffer size and send threshold\n"
    4365             :              "Size of the buffer\n"
    4366             :              "Send threshold\n")
    4367             : {
    4368           0 :         netlink_set_batch_buffer_size(0, 0, false);
    4369             : 
    4370           0 :         return CMD_SUCCESS;
    4371             : }
    4372             : 
    4373           0 : DEFPY (zebra_protodown_bit,
    4374             :        zebra_protodown_bit_cmd,
    4375             :        "zebra protodown reason-bit (0-31)$bit",
    4376             :        ZEBRA_STR
    4377             :        "Protodown Configuration\n"
    4378             :        "Reason Bit used in the kernel for application\n"
    4379             :        "Reason Bit range\n")
    4380             : {
    4381           0 :         if_netlink_set_frr_protodown_r_bit(bit);
    4382           0 :         return CMD_SUCCESS;
    4383             : }
    4384             : 
    4385           0 : DEFPY (no_zebra_protodown_bit,
    4386             :        no_zebra_protodown_bit_cmd,
    4387             :        "no zebra protodown reason-bit [(0-31)$bit]",
    4388             :        NO_STR
    4389             :        ZEBRA_STR
    4390             :        "Protodown Configuration\n"
    4391             :        "Reason Bit used in the kernel for setting protodown\n"
    4392             :        "Reason Bit Range\n")
    4393             : {
    4394           0 :         if_netlink_unset_frr_protodown_r_bit();
    4395           0 :         return CMD_SUCCESS;
    4396             : }
    4397             : 
    4398             : #endif /* HAVE_NETLINK */
    4399             : 
    4400           0 : DEFUN(ip_table_range, ip_table_range_cmd,
    4401             :       "[no] ip table range (1-4294967295) (1-4294967295)",
    4402             :       NO_STR IP_STR
    4403             :       "table configuration\n"
    4404             :       "Configure table range\n"
    4405             :       "Start Routing Table\n"
    4406             :       "End Routing Table\n")
    4407             : {
    4408           0 :         ZEBRA_DECLVAR_CONTEXT_VRF(vrf, zvrf);
    4409             : 
    4410           0 :         if (!zvrf)
    4411             :                 return CMD_WARNING;
    4412             : 
    4413           0 :         if (zvrf_id(zvrf) != VRF_DEFAULT && !vrf_is_backend_netns()) {
    4414           0 :                 vty_out(vty,
    4415             :                         "VRF subcommand does not make any sense in l3mdev based vrf's\n");
    4416           0 :                 return CMD_WARNING;
    4417             :         }
    4418             : 
    4419           0 :         if (strmatch(argv[0]->text, "no"))
    4420           0 :                 return table_manager_range(vty, false, zvrf, NULL, NULL);
    4421             : 
    4422           0 :         return table_manager_range(vty, true, zvrf, argv[3]->arg, argv[4]->arg);
    4423             : }
    4424             : 
    4425             : #ifdef HAVE_SCRIPTING
    4426             : 
    4427             : DEFUN(zebra_on_rib_process_script, zebra_on_rib_process_script_cmd,
    4428             :       "zebra on-rib-process script SCRIPT",
    4429             :       ZEBRA_STR
    4430             :       "on_rib_process_dplane_results hook call\n"
    4431             :       "Set a script\n"
    4432             :       "Script name (same as filename in /etc/frr/scripts/, without .lua)\n")
    4433             : {
    4434             : 
    4435             :         if (frrscript_names_set_script_name(ZEBRA_ON_RIB_PROCESS_HOOK_CALL,
    4436             :                                             argv[3]->arg)
    4437             :             == 0) {
    4438             :                 vty_out(vty, "Successfully added script %s for hook call %s\n",
    4439             :                         argv[3]->arg, ZEBRA_ON_RIB_PROCESS_HOOK_CALL);
    4440             :         } else {
    4441             :                 vty_out(vty, "Failed to add script %s for hook call %s\n",
    4442             :                         argv[3]->arg, ZEBRA_ON_RIB_PROCESS_HOOK_CALL);
    4443             :         }
    4444             :         return CMD_SUCCESS;
    4445             : }
    4446             : 
    4447             : #endif /* HAVE_SCRIPTING */
    4448             : 
    4449             : /* IP node for static routes. */
    4450             : static int zebra_ip_config(struct vty *vty);
    4451             : static struct cmd_node ip_node = {
    4452             :         .name = "static ip",
    4453             :         .node = IP_NODE,
    4454             :         .prompt = "",
    4455             :         .config_write = zebra_ip_config,
    4456             : };
    4457             : static int config_write_protocol(struct vty *vty);
    4458             : static struct cmd_node protocol_node = {
    4459             :         .name = "protocol",
    4460             :         .node = PROTOCOL_NODE,
    4461             :         .prompt = "",
    4462             :         .config_write = config_write_protocol,
    4463             : };
    4464             : /* table node for routing tables. */
    4465             : static int config_write_table(struct vty *vty);
    4466             : static struct cmd_node table_node = {
    4467             :         .name = "table",
    4468             :         .node = TABLE_NODE,
    4469             :         .prompt = "",
    4470             :         .config_write = config_write_table,
    4471             : };
    4472             : static int config_write_forwarding(struct vty *vty);
    4473             : static struct cmd_node forwarding_node = {
    4474             :         .name = "forwarding",
    4475             :         .node = FORWARDING_NODE,
    4476             :         .prompt = "",
    4477             :         .config_write = config_write_forwarding,
    4478             : };
    4479             : 
    4480             : /* Route VTY.  */
    4481           8 : void zebra_vty_init(void)
    4482             : {
    4483             :         /* Install configuration write function. */
    4484           8 :         install_node(&table_node);
    4485           8 :         install_node(&forwarding_node);
    4486             : 
    4487           8 :         install_element(VIEW_NODE, &show_ip_forwarding_cmd);
    4488           8 :         install_element(CONFIG_NODE, &ip_forwarding_cmd);
    4489           8 :         install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
    4490           8 :         install_element(ENABLE_NODE, &show_zebra_cmd);
    4491             : 
    4492           8 :         install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
    4493           8 :         install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
    4494           8 :         install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
    4495             : 
    4496             :         /* Route-map */
    4497           8 :         zebra_route_map_init();
    4498             : 
    4499           8 :         install_node(&ip_node);
    4500           8 :         install_node(&protocol_node);
    4501             : 
    4502           8 :         install_element(CONFIG_NODE, &allow_external_route_update_cmd);
    4503           8 :         install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
    4504             : 
    4505           8 :         install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
    4506           8 :         install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
    4507             : 
    4508           8 :         install_element(CONFIG_NODE, &zebra_nexthop_group_keep_cmd);
    4509           8 :         install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
    4510           8 :         install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
    4511           8 :         install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
    4512           8 :         install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
    4513           8 :         install_element(CONFIG_NODE, &zebra_packet_process_cmd);
    4514           8 :         install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
    4515           8 :         install_element(CONFIG_NODE, &nexthop_group_use_enable_cmd);
    4516           8 :         install_element(CONFIG_NODE, &proto_nexthop_group_only_cmd);
    4517           8 :         install_element(CONFIG_NODE, &backup_nexthop_recursive_use_enable_cmd);
    4518             : 
    4519           8 :         install_element(VIEW_NODE, &show_nexthop_group_cmd);
    4520           8 :         install_element(VIEW_NODE, &show_interface_nexthop_group_cmd);
    4521             : 
    4522           8 :         install_element(VIEW_NODE, &show_vrf_cmd);
    4523           8 :         install_element(VIEW_NODE, &show_vrf_vni_cmd);
    4524           8 :         install_element(VIEW_NODE, &show_route_cmd);
    4525           8 :         install_element(VIEW_NODE, &show_ro_cmd);
    4526           8 :         install_element(VIEW_NODE, &show_route_detail_cmd);
    4527           8 :         install_element(VIEW_NODE, &show_route_summary_cmd);
    4528           8 :         install_element(VIEW_NODE, &show_ip_nht_cmd);
    4529             : 
    4530           8 :         install_element(VIEW_NODE, &show_ip_rpf_cmd);
    4531           8 :         install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
    4532             : 
    4533           8 :         install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
    4534           8 :         install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
    4535           8 :         install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
    4536           8 :         install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
    4537           8 :         install_element(VRF_NODE, &ip_nht_default_route_cmd);
    4538           8 :         install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
    4539           8 :         install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
    4540           8 :         install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
    4541           8 :         install_element(CONFIG_NODE, &rnh_hide_backups_cmd);
    4542             : 
    4543           8 :         install_element(VIEW_NODE, &show_frr_cmd);
    4544           8 :         install_element(VIEW_NODE, &show_evpn_global_cmd);
    4545           8 :         install_element(VIEW_NODE, &show_evpn_vni_cmd);
    4546           8 :         install_element(VIEW_NODE, &show_evpn_vni_detail_cmd);
    4547           8 :         install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
    4548           8 :         install_element(VIEW_NODE, &show_evpn_l2_nh_cmd);
    4549           8 :         install_element(VIEW_NODE, &show_evpn_es_cmd);
    4550           8 :         install_element(VIEW_NODE, &show_evpn_es_evi_cmd);
    4551           8 :         install_element(VIEW_NODE, &show_evpn_access_vlan_cmd);
    4552           8 :         install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
    4553           8 :         install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
    4554           8 :         install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
    4555           8 :         install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
    4556           8 :         install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
    4557           8 :         install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
    4558           8 :         install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
    4559           8 :         install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
    4560           8 :         install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
    4561           8 :         install_element(VIEW_NODE, &show_evpn_mac_vni_detail_cmd);
    4562           8 :         install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
    4563           8 :         install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
    4564           8 :         install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
    4565           8 :         install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
    4566           8 :         install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
    4567           8 :         install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
    4568           8 :         install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
    4569           8 :         install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
    4570           8 :         install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
    4571           8 :         install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
    4572           8 :         install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
    4573           8 :         install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
    4574           8 :         install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
    4575           8 :         install_element(CONFIG_NODE, &evpn_accept_bgp_seq_cmd);
    4576           8 :         install_element(CONFIG_NODE, &no_evpn_accept_bgp_seq_cmd);
    4577             : 
    4578           8 :         install_element(VIEW_NODE, &show_neigh_cmd);
    4579             : 
    4580           8 :         install_element(VIEW_NODE, &show_pbr_ipset_cmd);
    4581           8 :         install_element(VIEW_NODE, &show_pbr_iptable_cmd);
    4582           8 :         install_element(VIEW_NODE, &show_pbr_rule_cmd);
    4583           8 :         install_element(CONFIG_NODE, &pbr_nexthop_resolve_cmd);
    4584           8 :         install_element(VIEW_NODE, &show_route_zebra_dump_cmd);
    4585             : 
    4586           8 :         install_element(CONFIG_NODE, &evpn_mh_mac_holdtime_cmd);
    4587           8 :         install_element(CONFIG_NODE, &evpn_mh_neigh_holdtime_cmd);
    4588           8 :         install_element(CONFIG_NODE, &evpn_mh_startup_delay_cmd);
    4589           8 :         install_element(CONFIG_NODE, &evpn_mh_redirect_off_cmd);
    4590           8 :         install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
    4591           8 :         install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
    4592           8 :         install_element(VRF_NODE, &vrf_vni_mapping_cmd);
    4593           8 :         install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
    4594             : 
    4595           8 :         install_element(VIEW_NODE, &show_dataplane_cmd);
    4596           8 :         install_element(VIEW_NODE, &show_dataplane_providers_cmd);
    4597           8 :         install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
    4598           8 :         install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
    4599             : 
    4600           8 :         install_element(CONFIG_NODE, &ip_table_range_cmd);
    4601           8 :         install_element(VRF_NODE, &ip_table_range_cmd);
    4602             : 
    4603             : #ifdef HAVE_NETLINK
    4604           8 :         install_element(CONFIG_NODE, &zebra_kernel_netlink_batch_tx_buf_cmd);
    4605           8 :         install_element(CONFIG_NODE, &no_zebra_kernel_netlink_batch_tx_buf_cmd);
    4606           8 :         install_element(CONFIG_NODE, &zebra_protodown_bit_cmd);
    4607           8 :         install_element(CONFIG_NODE, &no_zebra_protodown_bit_cmd);
    4608             : #endif /* HAVE_NETLINK */
    4609             : 
    4610             : #ifdef HAVE_SCRIPTING
    4611             :         install_element(CONFIG_NODE, &zebra_on_rib_process_script_cmd);
    4612             : #endif /* HAVE_SCRIPTING */
    4613             : 
    4614           8 :         install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
    4615           8 : }

Generated by: LCOV version v1.16-topotato