back to topotato report
topotato coverage report
Current view: top level - pimd - pim_cmd.c (source / functions) Hit Total Coverage
Test: test_pim_cbsr.py::PIMCandidateBSRTest Lines: 310 2754 11.3 %
Date: 2023-02-16 02:09:14 Functions: 5 181 2.8 %

          Line data    Source code
       1             : /*
       2             :  * PIM for Quagga
       3             :  * Copyright (C) 2008  Everton da Silva Marques
       4             :  *
       5             :  * This program is free software; you can redistribute it and/or modify
       6             :  * it under the terms of the GNU General Public License as published by
       7             :  * the Free Software Foundation; either version 2 of the License, or
       8             :  * (at your option) any later version.
       9             :  *
      10             :  * This program is distributed in the hope that it will be useful, but
      11             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :  * General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU General Public License along
      16             :  * with this program; see the file COPYING; if not, write to the Free Software
      17             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      18             :  */
      19             : 
      20             : #include <zebra.h>
      21             : 
      22             : #include "lib/json.h"
      23             : #include "command.h"
      24             : #include "if.h"
      25             : #include "prefix.h"
      26             : #include "zclient.h"
      27             : #include "plist.h"
      28             : #include "hash.h"
      29             : #include "nexthop.h"
      30             : #include "vrf.h"
      31             : #include "ferr.h"
      32             : 
      33             : #include "pimd.h"
      34             : #include "pim_mroute.h"
      35             : #include "pim_cmd.h"
      36             : #include "pim_iface.h"
      37             : #include "pim_vty.h"
      38             : #include "pim_mroute.h"
      39             : #include "pim_str.h"
      40             : #include "pim_igmp.h"
      41             : #include "pim_igmpv3.h"
      42             : #include "pim_sock.h"
      43             : #include "pim_time.h"
      44             : #include "pim_util.h"
      45             : #include "pim_oil.h"
      46             : #include "pim_neighbor.h"
      47             : #include "pim_pim.h"
      48             : #include "pim_ifchannel.h"
      49             : #include "pim_hello.h"
      50             : #include "pim_msg.h"
      51             : #include "pim_upstream.h"
      52             : #include "pim_rpf.h"
      53             : #include "pim_macro.h"
      54             : #include "pim_ssmpingd.h"
      55             : #include "pim_zebra.h"
      56             : #include "pim_static.h"
      57             : #include "pim_rp.h"
      58             : #include "pim_zlookup.h"
      59             : #include "pim_msdp.h"
      60             : #include "pim_ssm.h"
      61             : #include "pim_nht.h"
      62             : #include "pim_bfd.h"
      63             : #include "pim_vxlan.h"
      64             : #include "pim_mlag.h"
      65             : #include "bfd.h"
      66             : #include "pim_bsm.h"
      67             : #include "lib/northbound_cli.h"
      68             : #include "pim_errors.h"
      69             : #include "pim_nb.h"
      70             : #include "pim_addr.h"
      71             : #include "pim_cmd_common.h"
      72             : 
      73             : #include "pimd/pim_cmd_clippy.c"
      74             : 
      75             : static struct cmd_node debug_node = {
      76             :         .name = "debug",
      77             :         .node = DEBUG_NODE,
      78             :         .prompt = "",
      79             :         .config_write = pim_debug_config_write,
      80             : };
      81             : 
      82           0 : static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
      83             :                                       const int argc, int *idx)
      84             : {
      85           0 :         struct vrf *vrf;
      86             : 
      87           0 :         if (argv_find(argv, argc, "NAME", idx))
      88           0 :                 vrf = vrf_lookup_by_name(argv[*idx]->arg);
      89             :         else
      90           0 :                 vrf = vrf_lookup_by_id(VRF_DEFAULT);
      91             : 
      92           0 :         if (!vrf)
      93           0 :                 vty_out(vty, "Specified VRF: %s does not exist\n",
      94           0 :                         argv[*idx]->arg);
      95             : 
      96           0 :         return vrf;
      97             : }
      98             : 
      99           0 : static void pim_show_assert_helper(struct vty *vty,
     100             :                                    struct pim_interface *pim_ifp,
     101             :                                    struct pim_ifchannel *ch, time_t now)
     102             : {
     103           0 :         char winner_str[INET_ADDRSTRLEN];
     104           0 :         struct in_addr ifaddr;
     105           0 :         char uptime[10];
     106           0 :         char timer[10];
     107           0 :         char buf[PREFIX_STRLEN];
     108             : 
     109           0 :         ifaddr = pim_ifp->primary_address;
     110             : 
     111           0 :         pim_inet4_dump("<assrt_win?>", ch->ifassert_winner, winner_str,
     112             :                        sizeof(winner_str));
     113             : 
     114           0 :         pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
     115           0 :         pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
     116             : 
     117           0 :         vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-6s %-15s %-8s %-5s\n",
     118           0 :                 ch->interface->name,
     119             :                 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
     120             :                 &ch->sg.grp, pim_ifchannel_ifassert_name(ch->ifassert_state),
     121             :                 winner_str, uptime, timer);
     122           0 : }
     123             : 
     124           0 : static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
     125             : {
     126           0 :         struct pim_interface *pim_ifp;
     127           0 :         struct pim_ifchannel *ch;
     128           0 :         struct interface *ifp;
     129           0 :         time_t now;
     130             : 
     131           0 :         now = pim_time_monotonic_sec();
     132             : 
     133           0 :         vty_out(vty,
     134             :                 "Interface        Address         Source          Group           State  Winner          Uptime   Timer\n");
     135             : 
     136           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     137           0 :                 pim_ifp = ifp->info;
     138           0 :                 if (!pim_ifp)
     139           0 :                         continue;
     140             : 
     141           0 :                 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
     142           0 :                         if (ch->ifassert_state == PIM_IFASSERT_NOINFO)
     143           0 :                                 continue;
     144             : 
     145           0 :                         pim_show_assert_helper(vty, pim_ifp, ch, now);
     146             :                 } /* scan interface channels */
     147             :         }
     148           0 : }
     149             : 
     150           0 : static void pim_show_assert_internal_helper(struct vty *vty,
     151             :                                             struct pim_interface *pim_ifp,
     152             :                                             struct pim_ifchannel *ch)
     153             : {
     154           0 :         struct in_addr ifaddr;
     155           0 :         char buf[PREFIX_STRLEN];
     156             : 
     157           0 :         ifaddr = pim_ifp->primary_address;
     158             : 
     159           0 :         vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %-3s %-3s %-4s\n",
     160           0 :                 ch->interface->name,
     161             :                 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
     162             :                 &ch->sg.grp,
     163           0 :                 PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
     164           0 :                 pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
     165           0 :                 PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes"
     166             :                 : "no",
     167           0 :                 pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no");
     168           0 : }
     169             : 
     170           0 : static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
     171             : {
     172           0 :         struct pim_interface *pim_ifp;
     173           0 :         struct pim_ifchannel *ch;
     174           0 :         struct interface *ifp;
     175             : 
     176           0 :         vty_out(vty,
     177             :                 "CA:   CouldAssert\n"
     178             :                 "ECA:  Evaluate CouldAssert\n"
     179             :                 "ATD:  AssertTrackingDesired\n"
     180             :                 "eATD: Evaluate AssertTrackingDesired\n\n");
     181             : 
     182           0 :         vty_out(vty,
     183             :                 "Interface        Address         Source          Group           CA  eCA ATD eATD\n");
     184           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     185           0 :                 pim_ifp = ifp->info;
     186           0 :                 if (!pim_ifp)
     187           0 :                         continue;
     188             : 
     189           0 :                 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
     190           0 :                         pim_show_assert_internal_helper(vty, pim_ifp, ch);
     191             :                 } /* scan interface channels */
     192             :         }
     193           0 : }
     194             : 
     195           0 : static void pim_show_assert_metric_helper(struct vty *vty,
     196             :                                           struct pim_interface *pim_ifp,
     197             :                                           struct pim_ifchannel *ch)
     198             : {
     199           0 :         char addr_str[INET_ADDRSTRLEN];
     200           0 :         struct pim_assert_metric am;
     201           0 :         struct in_addr ifaddr;
     202           0 :         char buf[PREFIX_STRLEN];
     203             : 
     204           0 :         ifaddr = pim_ifp->primary_address;
     205             : 
     206           0 :         am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
     207             :                                          pim_ifp->primary_address);
     208             : 
     209           0 :         pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
     210             : 
     211           0 :         vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %4u %6u %-15s\n",
     212           0 :                 ch->interface->name,
     213             :                 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
     214           0 :                 &ch->sg.grp, am.rpt_bit_flag ? "yes" : "no",
     215             :                 am.metric_preference, am.route_metric, addr_str);
     216           0 : }
     217             : 
     218           0 : static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
     219             : {
     220           0 :         struct pim_interface *pim_ifp;
     221           0 :         struct pim_ifchannel *ch;
     222           0 :         struct interface *ifp;
     223             : 
     224           0 :         vty_out(vty,
     225             :                 "Interface        Address         Source          Group           RPT Pref Metric Address        \n");
     226             : 
     227           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     228           0 :                 pim_ifp = ifp->info;
     229           0 :                 if (!pim_ifp)
     230           0 :                         continue;
     231             : 
     232           0 :                 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
     233           0 :                         pim_show_assert_metric_helper(vty, pim_ifp, ch);
     234             :                 } /* scan interface channels */
     235             :         }
     236           0 : }
     237             : 
     238           0 : static void pim_show_assert_winner_metric_helper(struct vty *vty,
     239             :                                                  struct pim_interface *pim_ifp,
     240             :                                                  struct pim_ifchannel *ch)
     241             : {
     242           0 :         char addr_str[INET_ADDRSTRLEN];
     243           0 :         struct pim_assert_metric *am;
     244           0 :         struct in_addr ifaddr;
     245           0 :         char pref_str[16];
     246           0 :         char metr_str[16];
     247           0 :         char buf[PREFIX_STRLEN];
     248             : 
     249           0 :         ifaddr = pim_ifp->primary_address;
     250             : 
     251           0 :         am = &ch->ifassert_winner_metric;
     252             : 
     253           0 :         pim_inet4_dump("<addr?>", am->ip_address, addr_str, sizeof(addr_str));
     254             : 
     255           0 :         if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
     256           0 :                 snprintf(pref_str, sizeof(pref_str), "INFI");
     257             :         else
     258           0 :                 snprintf(pref_str, sizeof(pref_str), "%4u",
     259             :                          am->metric_preference);
     260             : 
     261           0 :         if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
     262           0 :                 snprintf(metr_str, sizeof(metr_str), "INFI");
     263             :         else
     264           0 :                 snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
     265             : 
     266           0 :         vty_out(vty, "%-16s %-15s %-15pPAs %-15pPAs %-3s %-4s %-6s %-15s\n",
     267           0 :                 ch->interface->name,
     268             :                 inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), &ch->sg.src,
     269           0 :                 &ch->sg.grp, am->rpt_bit_flag ? "yes" : "no", pref_str,
     270             :                 metr_str, addr_str);
     271           0 : }
     272             : 
     273           0 : static void pim_show_assert_winner_metric(struct pim_instance *pim,
     274             :                                           struct vty *vty)
     275             : {
     276           0 :         struct pim_interface *pim_ifp;
     277           0 :         struct pim_ifchannel *ch;
     278           0 :         struct interface *ifp;
     279             : 
     280           0 :         vty_out(vty,
     281             :                 "Interface        Address         Source          Group           RPT Pref Metric Address        \n");
     282             : 
     283           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     284           0 :                 pim_ifp = ifp->info;
     285           0 :                 if (!pim_ifp)
     286           0 :                         continue;
     287             : 
     288           0 :                 RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
     289           0 :                         pim_show_assert_winner_metric_helper(vty, pim_ifp, ch);
     290             :                 } /* scan interface channels */
     291             :         }
     292           0 : }
     293             : 
     294           0 : static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
     295             :                                  bool uj)
     296             : {
     297           0 :         struct interface *ifp;
     298           0 :         time_t now;
     299           0 :         char buf[PREFIX_STRLEN];
     300           0 :         json_object *json = NULL;
     301           0 :         json_object *json_row = NULL;
     302             : 
     303           0 :         now = pim_time_monotonic_sec();
     304             : 
     305           0 :         if (uj)
     306           0 :                 json = json_object_new_object();
     307             :         else
     308           0 :                 vty_out(vty,
     309             :                         "Interface         State          Address  V  Querier          QuerierIp  Query Timer    Uptime\n");
     310             : 
     311           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     312           0 :                 struct pim_interface *pim_ifp;
     313           0 :                 struct listnode *sock_node;
     314           0 :                 struct gm_sock *igmp;
     315             : 
     316           0 :                 pim_ifp = ifp->info;
     317             : 
     318           0 :                 if (!pim_ifp)
     319           0 :                         continue;
     320             : 
     321           0 :                 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
     322             :                                           igmp)) {
     323           0 :                         char uptime[10];
     324           0 :                         char query_hhmmss[10];
     325             : 
     326           0 :                         pim_time_uptime(uptime, sizeof(uptime),
     327           0 :                                         now - igmp->sock_creation);
     328           0 :                         pim_time_timer_to_hhmmss(query_hhmmss,
     329             :                                                  sizeof(query_hhmmss),
     330             :                                                  igmp->t_igmp_query_timer);
     331             : 
     332           0 :                         if (uj) {
     333           0 :                                 json_row = json_object_new_object();
     334           0 :                                 json_object_pim_ifp_add(json_row, ifp);
     335           0 :                                 json_object_string_add(json_row, "upTime",
     336             :                                                        uptime);
     337           0 :                                 json_object_int_add(json_row, "version",
     338           0 :                                                     pim_ifp->igmp_version);
     339             : 
     340           0 :                                 if (igmp->t_igmp_query_timer) {
     341           0 :                                         json_object_boolean_true_add(json_row,
     342             :                                                                      "querier");
     343           0 :                                         json_object_string_add(json_row,
     344             :                                                                "queryTimer",
     345             :                                                                query_hhmmss);
     346             :                                 }
     347           0 :                                 json_object_string_addf(json_row, "querierIp",
     348             :                                                         "%pI4",
     349             :                                                         &igmp->querier_addr);
     350             : 
     351           0 :                                 json_object_object_add(json, ifp->name,
     352             :                                                        json_row);
     353             : 
     354           0 :                                 if (igmp->mtrace_only) {
     355           0 :                                         json_object_boolean_true_add(
     356             :                                                 json_row, "mtraceOnly");
     357             :                                 }
     358             :                         } else {
     359           0 :                                 vty_out(vty,
     360             :                                         "%-16s  %5s  %15s  %d  %7s  %17pI4  %11s  %8s\n",
     361           0 :                                         ifp->name,
     362           0 :                                         if_is_up(ifp)
     363           0 :                                                 ? (igmp->mtrace_only ? "mtrc"
     364           0 :                                                                      : "up")
     365             :                                                 : "down",
     366           0 :                                         inet_ntop(AF_INET, &igmp->ifaddr, buf,
     367             :                                                   sizeof(buf)),
     368             :                                         pim_ifp->igmp_version,
     369           0 :                                         igmp->t_igmp_query_timer ? "local"
     370             :                                                                  : "other",
     371             :                                         &igmp->querier_addr, query_hhmmss,
     372             :                                         uptime);
     373             :                         }
     374             :                 }
     375             :         }
     376             : 
     377           0 :         if (uj)
     378           0 :                 vty_json(vty, json);
     379           0 : }
     380             : 
     381           0 : static void igmp_show_interfaces_single(struct pim_instance *pim,
     382             :                                         struct vty *vty, const char *ifname,
     383             :                                         bool uj)
     384             : {
     385           0 :         struct gm_sock *igmp;
     386           0 :         struct interface *ifp;
     387           0 :         struct listnode *sock_node;
     388           0 :         struct pim_interface *pim_ifp;
     389           0 :         char uptime[10];
     390           0 :         char query_hhmmss[10];
     391           0 :         char other_hhmmss[10];
     392           0 :         int found_ifname = 0;
     393           0 :         int sqi;
     394           0 :         long gmi_msec; /* Group Membership Interval */
     395           0 :         long lmqt_msec;
     396           0 :         long ohpi_msec;
     397           0 :         long oqpi_msec; /* Other Querier Present Interval */
     398           0 :         long qri_msec;
     399           0 :         time_t now;
     400           0 :         int lmqc;
     401             : 
     402           0 :         json_object *json = NULL;
     403           0 :         json_object *json_row = NULL;
     404             : 
     405           0 :         if (uj)
     406           0 :                 json = json_object_new_object();
     407             : 
     408           0 :         now = pim_time_monotonic_sec();
     409             : 
     410           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     411           0 :                 pim_ifp = ifp->info;
     412             : 
     413           0 :                 if (!pim_ifp)
     414           0 :                         continue;
     415             : 
     416           0 :                 if (strcmp(ifname, "detail") && strcmp(ifname, ifp->name))
     417           0 :                         continue;
     418             : 
     419           0 :                 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
     420             :                                           igmp)) {
     421           0 :                         found_ifname = 1;
     422           0 :                         pim_time_uptime(uptime, sizeof(uptime),
     423           0 :                                         now - igmp->sock_creation);
     424           0 :                         pim_time_timer_to_hhmmss(query_hhmmss,
     425             :                                                  sizeof(query_hhmmss),
     426             :                                                  igmp->t_igmp_query_timer);
     427           0 :                         pim_time_timer_to_hhmmss(other_hhmmss,
     428             :                                                  sizeof(other_hhmmss),
     429             :                                                  igmp->t_other_querier_timer);
     430             : 
     431           0 :                         gmi_msec = PIM_IGMP_GMI_MSEC(
     432             :                                 igmp->querier_robustness_variable,
     433             :                                 igmp->querier_query_interval,
     434             :                                 pim_ifp->gm_query_max_response_time_dsec);
     435             : 
     436           0 :                         sqi = PIM_IGMP_SQI(pim_ifp->gm_default_query_interval);
     437             : 
     438           0 :                         oqpi_msec = PIM_IGMP_OQPI_MSEC(
     439             :                                 igmp->querier_robustness_variable,
     440             :                                 igmp->querier_query_interval,
     441             :                                 pim_ifp->gm_query_max_response_time_dsec);
     442             : 
     443           0 :                         lmqt_msec = PIM_IGMP_LMQT_MSEC(
     444             :                                 pim_ifp->gm_specific_query_max_response_time_dsec,
     445             :                                 pim_ifp->gm_last_member_query_count);
     446             : 
     447           0 :                         ohpi_msec =
     448           0 :                                 PIM_IGMP_OHPI_DSEC(
     449             :                                         igmp->querier_robustness_variable,
     450             :                                         igmp->querier_query_interval,
     451           0 :                                         pim_ifp->gm_query_max_response_time_dsec) *
     452             :                                 100;
     453             : 
     454           0 :                         qri_msec =
     455             :                                 pim_ifp->gm_query_max_response_time_dsec * 100;
     456           0 :                         lmqc = pim_ifp->gm_last_member_query_count;
     457             : 
     458           0 :                         if (uj) {
     459           0 :                                 json_row = json_object_new_object();
     460           0 :                                 json_object_pim_ifp_add(json_row, ifp);
     461           0 :                                 json_object_string_add(json_row, "upTime",
     462             :                                                        uptime);
     463           0 :                                 json_object_string_add(json_row, "querier",
     464           0 :                                                        igmp->t_igmp_query_timer
     465             :                                                        ? "local"
     466             :                                                        : "other");
     467           0 :                                 json_object_string_addf(json_row, "querierIp",
     468             :                                                         "%pI4",
     469             :                                                         &igmp->querier_addr);
     470           0 :                                 json_object_int_add(json_row, "queryStartCount",
     471           0 :                                                     igmp->startup_query_count);
     472           0 :                                 json_object_string_add(json_row,
     473             :                                                        "queryQueryTimer",
     474             :                                                        query_hhmmss);
     475           0 :                                 json_object_string_add(json_row,
     476             :                                                        "queryOtherTimer",
     477             :                                                        other_hhmmss);
     478           0 :                                 json_object_int_add(json_row, "version",
     479           0 :                                                     pim_ifp->igmp_version);
     480           0 :                                 json_object_int_add(
     481             :                                         json_row,
     482             :                                         "timerGroupMembershipIntervalMsec",
     483             :                                         gmi_msec);
     484           0 :                                 json_object_int_add(json_row,
     485             :                                                     "lastMemberQueryCount",
     486             :                                                     lmqc);
     487           0 :                                 json_object_int_add(json_row,
     488             :                                                     "timerLastMemberQueryMsec",
     489             :                                                     lmqt_msec);
     490           0 :                                 json_object_int_add(
     491             :                                         json_row,
     492             :                                         "timerOlderHostPresentIntervalMsec",
     493             :                                         ohpi_msec);
     494           0 :                                 json_object_int_add(
     495             :                                         json_row,
     496             :                                         "timerOtherQuerierPresentIntervalMsec",
     497             :                                         oqpi_msec);
     498           0 :                                 json_object_int_add(
     499             :                                         json_row, "timerQueryInterval",
     500           0 :                                         igmp->querier_query_interval);
     501           0 :                                 json_object_int_add(
     502             :                                         json_row,
     503             :                                         "timerQueryResponseIntervalMsec",
     504             :                                         qri_msec);
     505           0 :                                 json_object_int_add(
     506             :                                         json_row, "timerRobustnessVariable",
     507           0 :                                         igmp->querier_robustness_variable);
     508           0 :                                 json_object_int_add(json_row,
     509             :                                                     "timerStartupQueryInterval",
     510             :                                                     sqi);
     511             : 
     512           0 :                                 json_object_object_add(json, ifp->name,
     513             :                                                        json_row);
     514             : 
     515           0 :                                 if (igmp->mtrace_only) {
     516           0 :                                         json_object_boolean_true_add(
     517             :                                                 json_row, "mtraceOnly");
     518             :                                 }
     519             :                         } else {
     520           0 :                                 vty_out(vty, "Interface : %s\n", ifp->name);
     521           0 :                                 vty_out(vty, "State     : %s\n",
     522           0 :                                         if_is_up(ifp) ? (igmp->mtrace_only ?
     523             :                                                          "mtrace"
     524           0 :                                                          : "up")
     525             :                                         : "down");
     526           0 :                                 vty_out(vty, "Address   : %pI4\n",
     527             :                                         &pim_ifp->primary_address);
     528           0 :                                 vty_out(vty, "Uptime    : %s\n", uptime);
     529           0 :                                 vty_out(vty, "Version   : %d\n",
     530             :                                         pim_ifp->igmp_version);
     531           0 :                                 vty_out(vty, "\n");
     532           0 :                                 vty_out(vty, "\n");
     533             : 
     534           0 :                                 vty_out(vty, "Querier\n");
     535           0 :                                 vty_out(vty, "-------\n");
     536           0 :                                 vty_out(vty, "Querier     : %s\n",
     537           0 :                                         igmp->t_igmp_query_timer ? "local"
     538             :                                         : "other");
     539           0 :                                 vty_out(vty, "QuerierIp   : %pI4",
     540             :                                         &igmp->querier_addr);
     541           0 :                                 if (pim_ifp->primary_address.s_addr
     542           0 :                                     == igmp->querier_addr.s_addr)
     543           0 :                                         vty_out(vty, " (this router)\n");
     544             :                                 else
     545           0 :                                         vty_out(vty, "\n");
     546             : 
     547           0 :                                 vty_out(vty, "Start Count : %d\n",
     548             :                                         igmp->startup_query_count);
     549           0 :                                 vty_out(vty, "Query Timer : %s\n",
     550             :                                         query_hhmmss);
     551           0 :                                 vty_out(vty, "Other Timer : %s\n",
     552             :                                         other_hhmmss);
     553           0 :                                 vty_out(vty, "\n");
     554           0 :                                 vty_out(vty, "\n");
     555             : 
     556           0 :                                 vty_out(vty, "Timers\n");
     557           0 :                                 vty_out(vty, "------\n");
     558           0 :                                 vty_out(vty,
     559             :                                         "Group Membership Interval      : %lis\n",
     560             :                                         gmi_msec / 1000);
     561           0 :                                 vty_out(vty,
     562             :                                         "Last Member Query Count        : %d\n",
     563             :                                         lmqc);
     564           0 :                                 vty_out(vty,
     565             :                                         "Last Member Query Time         : %lis\n",
     566             :                                         lmqt_msec / 1000);
     567           0 :                                 vty_out(vty,
     568             :                                         "Older Host Present Interval    : %lis\n",
     569             :                                         ohpi_msec / 1000);
     570           0 :                                 vty_out(vty,
     571             :                                         "Other Querier Present Interval : %lis\n",
     572             :                                         oqpi_msec / 1000);
     573           0 :                                 vty_out(vty,
     574             :                                         "Query Interval                 : %ds\n",
     575             :                                         igmp->querier_query_interval);
     576           0 :                                 vty_out(vty,
     577             :                                         "Query Response Interval        : %lis\n",
     578             :                                         qri_msec / 1000);
     579           0 :                                 vty_out(vty,
     580             :                                         "Robustness Variable            : %d\n",
     581             :                                         igmp->querier_robustness_variable);
     582           0 :                                 vty_out(vty,
     583             :                                         "Startup Query Interval         : %ds\n",
     584             :                                         sqi);
     585           0 :                                 vty_out(vty, "\n");
     586           0 :                                 vty_out(vty, "\n");
     587             : 
     588           0 :                                 pim_print_ifp_flags(vty, ifp);
     589             :                         }
     590             :                 }
     591             :         }
     592             : 
     593           0 :         if (uj)
     594           0 :                 vty_json(vty, json);
     595           0 :         else if (!found_ifname)
     596           0 :                 vty_out(vty, "%% No such interface\n");
     597           0 : }
     598             : 
     599           0 : static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty,
     600             :                                      bool uj)
     601             : {
     602           0 :         struct interface *ifp;
     603           0 :         time_t now;
     604           0 :         json_object *json = NULL;
     605           0 :         json_object *json_iface = NULL;
     606           0 :         json_object *json_grp = NULL;
     607           0 :         json_object *json_grp_arr = NULL;
     608             : 
     609           0 :         now = pim_time_monotonic_sec();
     610             : 
     611           0 :         if (uj) {
     612           0 :                 json = json_object_new_object();
     613           0 :                 json_object_string_add(json, "vrf",
     614           0 :                                        vrf_id_to_name(pim->vrf->vrf_id));
     615             :         } else {
     616           0 :                 vty_out(vty,
     617             :                         "Interface        Address         Source          Group           Socket Uptime  \n");
     618             :         }
     619             : 
     620           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     621           0 :                 struct pim_interface *pim_ifp;
     622           0 :                 struct listnode *join_node;
     623           0 :                 struct gm_join *ij;
     624           0 :                 struct in_addr pri_addr;
     625           0 :                 char pri_addr_str[INET_ADDRSTRLEN];
     626             : 
     627           0 :                 pim_ifp = ifp->info;
     628             : 
     629           0 :                 if (!pim_ifp)
     630           0 :                         continue;
     631             : 
     632           0 :                 if (!pim_ifp->gm_join_list)
     633           0 :                         continue;
     634             : 
     635           0 :                 pri_addr = pim_find_primary_addr(ifp);
     636           0 :                 pim_inet4_dump("<pri?>", pri_addr, pri_addr_str,
     637             :                                sizeof(pri_addr_str));
     638             : 
     639           0 :                 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_join_list, join_node,
     640             :                                           ij)) {
     641           0 :                         char group_str[INET_ADDRSTRLEN];
     642           0 :                         char source_str[INET_ADDRSTRLEN];
     643           0 :                         char uptime[10];
     644             : 
     645           0 :                         pim_time_uptime(uptime, sizeof(uptime),
     646           0 :                                         now - ij->sock_creation);
     647           0 :                         pim_inet4_dump("<grp?>", ij->group_addr, group_str,
     648             :                                        sizeof(group_str));
     649           0 :                         pim_inet4_dump("<src?>", ij->source_addr, source_str,
     650             :                                        sizeof(source_str));
     651             : 
     652           0 :                         if (uj) {
     653           0 :                                 json_object_object_get_ex(json, ifp->name,
     654             :                                                           &json_iface);
     655             : 
     656           0 :                                 if (!json_iface) {
     657           0 :                                         json_iface = json_object_new_object();
     658           0 :                                         json_object_string_add(
     659             :                                                 json_iface, "name", ifp->name);
     660           0 :                                         json_object_object_add(json, ifp->name,
     661             :                                                                json_iface);
     662           0 :                                         json_grp_arr = json_object_new_array();
     663           0 :                                         json_object_object_add(json_iface,
     664             :                                                                "groups",
     665             :                                                                json_grp_arr);
     666             :                                 }
     667             : 
     668           0 :                                 json_grp = json_object_new_object();
     669           0 :                                 json_object_string_add(json_grp, "source",
     670             :                                                        source_str);
     671           0 :                                 json_object_string_add(json_grp, "group",
     672             :                                                        group_str);
     673           0 :                                 json_object_string_add(json_grp, "primaryAddr",
     674             :                                                        pri_addr_str);
     675           0 :                                 json_object_int_add(json_grp, "sockFd",
     676           0 :                                                     ij->sock_fd);
     677           0 :                                 json_object_string_add(json_grp, "upTime",
     678             :                                                        uptime);
     679           0 :                                 json_object_array_add(json_grp_arr, json_grp);
     680             :                         } else {
     681           0 :                                 vty_out(vty,
     682             :                                         "%-16s %-15s %-15s %-15s %6d %8s\n",
     683           0 :                                         ifp->name, pri_addr_str, source_str,
     684             :                                         group_str, ij->sock_fd, uptime);
     685             :                         }
     686             :                 } /* for (pim_ifp->gm_join_list) */
     687             : 
     688             :         } /* for (iflist) */
     689             : 
     690           0 :         if (uj)
     691           0 :                 vty_json(vty, json);
     692           0 : }
     693             : 
     694           0 : static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
     695             :                                  const char *ifname, bool uj)
     696             : {
     697           0 :         struct interface *ifp;
     698           0 :         struct igmp_stats igmp_stats;
     699           0 :         bool found_ifname = false;
     700           0 :         json_object *json = NULL;
     701             : 
     702           0 :         igmp_stats_init(&igmp_stats);
     703             : 
     704           0 :         if (uj)
     705           0 :                 json = json_object_new_object();
     706             : 
     707           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     708           0 :                 struct pim_interface *pim_ifp;
     709           0 :                 struct listnode *sock_node, *source_node, *group_node;
     710           0 :                 struct gm_sock *igmp;
     711           0 :                 struct gm_group *group;
     712           0 :                 struct gm_source *src;
     713             : 
     714           0 :                 pim_ifp = ifp->info;
     715             : 
     716           0 :                 if (!pim_ifp)
     717           0 :                         continue;
     718             : 
     719           0 :                 if (ifname && strcmp(ifname, ifp->name))
     720           0 :                         continue;
     721             : 
     722           0 :                 found_ifname = true;
     723             : 
     724           0 :                 igmp_stats.joins_failed += pim_ifp->igmp_ifstat_joins_failed;
     725           0 :                 igmp_stats.joins_sent += pim_ifp->igmp_ifstat_joins_sent;
     726           0 :                 igmp_stats.total_groups +=
     727           0 :                         pim_ifp->gm_group_list
     728             :                                 ? listcount(pim_ifp->gm_group_list)
     729           0 :                                 : 0;
     730           0 :                 igmp_stats.peak_groups += pim_ifp->igmp_peak_group_count;
     731             : 
     732             : 
     733           0 :                 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, group_node,
     734             :                                           group)) {
     735           0 :                         for (ALL_LIST_ELEMENTS_RO(group->group_source_list,
     736             :                                                   source_node, src)) {
     737           0 :                                 if (pim_addr_is_any(src->source_addr))
     738           0 :                                         continue;
     739             : 
     740           0 :                                 igmp_stats.total_source_groups++;
     741             :                         }
     742             :                 }
     743             : 
     744           0 :                 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_socket_list, sock_node,
     745             :                                           igmp)) {
     746           0 :                         igmp_stats_add(&igmp_stats, &igmp->igmp_stats);
     747             :                 }
     748             :         }
     749             : 
     750           0 :         if (!found_ifname) {
     751           0 :                 if (uj)
     752           0 :                         vty_json(vty, json);
     753             :                 else
     754           0 :                         vty_out(vty, "%% No such interface\n");
     755           0 :                 return;
     756             :         }
     757             : 
     758           0 :         if (uj) {
     759           0 :                 json_object *json_row = json_object_new_object();
     760             : 
     761           0 :                 json_object_string_add(json_row, "name",
     762             :                                        ifname ? ifname : "global");
     763           0 :                 json_object_int_add(json_row, "queryV1", igmp_stats.query_v1);
     764           0 :                 json_object_int_add(json_row, "queryV2", igmp_stats.query_v2);
     765           0 :                 json_object_int_add(json_row, "queryV3", igmp_stats.query_v3);
     766           0 :                 json_object_int_add(json_row, "leaveV2", igmp_stats.leave_v2);
     767           0 :                 json_object_int_add(json_row, "reportV1", igmp_stats.report_v1);
     768           0 :                 json_object_int_add(json_row, "reportV2", igmp_stats.report_v2);
     769           0 :                 json_object_int_add(json_row, "reportV3", igmp_stats.report_v3);
     770           0 :                 json_object_int_add(json_row, "mtraceResponse",
     771           0 :                                     igmp_stats.mtrace_rsp);
     772           0 :                 json_object_int_add(json_row, "mtraceRequest",
     773           0 :                                     igmp_stats.mtrace_req);
     774           0 :                 json_object_int_add(json_row, "unsupported",
     775           0 :                                     igmp_stats.unsupported);
     776           0 :                 json_object_int_add(json_row, "totalReceivedMessages",
     777           0 :                                     igmp_stats.total_recv_messages);
     778           0 :                 json_object_int_add(json_row, "peakGroups",
     779           0 :                                     igmp_stats.peak_groups);
     780           0 :                 json_object_int_add(json_row, "totalGroups",
     781           0 :                                     igmp_stats.total_groups);
     782           0 :                 json_object_int_add(json_row, "totalSourceGroups",
     783           0 :                                     igmp_stats.total_source_groups);
     784           0 :                 json_object_int_add(json_row, "joinsFailed",
     785           0 :                                     igmp_stats.joins_failed);
     786           0 :                 json_object_int_add(json_row, "joinsSent",
     787           0 :                                     igmp_stats.joins_sent);
     788           0 :                 json_object_int_add(json_row, "generalQueriesSent",
     789           0 :                                     igmp_stats.general_queries_sent);
     790           0 :                 json_object_int_add(json_row, "groupQueriesSent",
     791           0 :                                     igmp_stats.group_queries_sent);
     792           0 :                 json_object_object_add(json, ifname ? ifname : "global",
     793             :                                        json_row);
     794           0 :                 vty_json(vty, json);
     795             :         } else {
     796           0 :                 vty_out(vty, "IGMP statistics\n");
     797           0 :                 vty_out(vty, "Interface               : %s\n",
     798             :                         ifname ? ifname : "global");
     799           0 :                 vty_out(vty, "V1 query                : %u\n",
     800             :                         igmp_stats.query_v1);
     801           0 :                 vty_out(vty, "V2 query                : %u\n",
     802             :                         igmp_stats.query_v2);
     803           0 :                 vty_out(vty, "V3 query                : %u\n",
     804             :                         igmp_stats.query_v3);
     805           0 :                 vty_out(vty, "V2 leave                : %u\n",
     806             :                         igmp_stats.leave_v2);
     807           0 :                 vty_out(vty, "V1 report               : %u\n",
     808             :                         igmp_stats.report_v1);
     809           0 :                 vty_out(vty, "V2 report               : %u\n",
     810             :                         igmp_stats.report_v2);
     811           0 :                 vty_out(vty, "V3 report               : %u\n",
     812             :                         igmp_stats.report_v3);
     813           0 :                 vty_out(vty, "mtrace response         : %u\n",
     814             :                         igmp_stats.mtrace_rsp);
     815           0 :                 vty_out(vty, "mtrace request          : %u\n",
     816             :                         igmp_stats.mtrace_req);
     817           0 :                 vty_out(vty, "unsupported             : %u\n",
     818             :                         igmp_stats.unsupported);
     819           0 :                 vty_out(vty, "total received messages : %u\n",
     820             :                         igmp_stats.total_recv_messages);
     821           0 :                 vty_out(vty, "joins failed            : %u\n",
     822             :                         igmp_stats.joins_failed);
     823           0 :                 vty_out(vty, "joins sent              : %u\n",
     824             :                         igmp_stats.joins_sent);
     825           0 :                 vty_out(vty, "general queries sent    : %u\n",
     826             :                         igmp_stats.general_queries_sent);
     827           0 :                 vty_out(vty, "group queries sent      : %u\n",
     828             :                         igmp_stats.group_queries_sent);
     829           0 :                 vty_out(vty, "peak groups             : %u\n",
     830             :                         igmp_stats.peak_groups);
     831           0 :                 vty_out(vty, "total groups            : %u\n",
     832             :                         igmp_stats.total_groups);
     833           0 :                 vty_out(vty, "total source groups     : %u\n",
     834             :                         igmp_stats.total_source_groups);
     835             :         }
     836             : }
     837             : 
     838           0 : static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
     839             : {
     840           0 :         struct interface *ifp;
     841           0 :         time_t now;
     842           0 :         json_object *json = NULL;
     843           0 :         json_object *json_iface = NULL;
     844           0 :         json_object *json_group = NULL;
     845           0 :         json_object *json_groups = NULL;
     846             : 
     847           0 :         now = pim_time_monotonic_sec();
     848             : 
     849           0 :         if (uj) {
     850           0 :                 json = json_object_new_object();
     851           0 :                 json_object_int_add(json, "totalGroups", pim->gm_group_count);
     852           0 :                 json_object_int_add(json, "watermarkLimit",
     853           0 :                                     pim->gm_watermark_limit);
     854             :         } else {
     855           0 :                 vty_out(vty, "Total IGMP groups: %u\n", pim->gm_group_count);
     856           0 :                 vty_out(vty, "Watermark warn limit(%s): %u\n",
     857             :                         pim->gm_watermark_limit ? "Set" : "Not Set",
     858             :                         pim->gm_watermark_limit);
     859           0 :                 vty_out(vty,
     860             :                         "Interface        Group           Mode Timer    Srcs V Uptime  \n");
     861             :         }
     862             : 
     863             :         /* scan interfaces */
     864           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     865           0 :                 struct pim_interface *pim_ifp = ifp->info;
     866           0 :                 struct listnode *grpnode;
     867           0 :                 struct gm_group *grp;
     868             : 
     869           0 :                 if (!pim_ifp)
     870           0 :                         continue;
     871             : 
     872             :                 /* scan igmp groups */
     873           0 :                 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
     874             :                                           grp)) {
     875           0 :                         char group_str[INET_ADDRSTRLEN];
     876           0 :                         char hhmmss[10];
     877           0 :                         char uptime[10];
     878             : 
     879           0 :                         pim_inet4_dump("<group?>", grp->group_addr, group_str,
     880             :                                        sizeof(group_str));
     881           0 :                         pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
     882             :                                                  grp->t_group_timer);
     883           0 :                         pim_time_uptime(uptime, sizeof(uptime),
     884           0 :                                         now - grp->group_creation);
     885             : 
     886           0 :                         if (uj) {
     887           0 :                                 json_object_object_get_ex(json, ifp->name,
     888             :                                                           &json_iface);
     889             : 
     890           0 :                                 if (!json_iface) {
     891           0 :                                         json_iface = json_object_new_object();
     892           0 :                                         json_object_pim_ifp_add(json_iface,
     893             :                                                                 ifp);
     894           0 :                                         json_object_object_add(json, ifp->name,
     895             :                                                                json_iface);
     896           0 :                                         json_groups = json_object_new_array();
     897           0 :                                         json_object_object_add(json_iface,
     898             :                                                                "groups",
     899             :                                                                json_groups);
     900             :                                 }
     901             : 
     902           0 :                                 json_group = json_object_new_object();
     903           0 :                                 json_object_string_add(json_group, "group",
     904             :                                                        group_str);
     905             : 
     906           0 :                                 if (grp->igmp_version == 3)
     907           0 :                                         json_object_string_add(
     908             :                                                 json_group, "mode",
     909           0 :                                                 grp->group_filtermode_isexcl
     910             :                                                         ? "EXCLUDE"
     911             :                                                         : "INCLUDE");
     912             : 
     913           0 :                                 json_object_string_add(json_group, "timer",
     914             :                                                        hhmmss);
     915           0 :                                 json_object_int_add(
     916             :                                         json_group, "sourcesCount",
     917           0 :                                         grp->group_source_list ? listcount(
     918             :                                                 grp->group_source_list)
     919             :                                                                : 0);
     920           0 :                                 json_object_int_add(json_group, "version",
     921           0 :                                                     grp->igmp_version);
     922           0 :                                 json_object_string_add(json_group, "uptime",
     923             :                                                        uptime);
     924           0 :                                 json_object_array_add(json_groups, json_group);
     925             :                         } else {
     926           0 :                                 vty_out(vty, "%-16s %-15s %4s %8s %4d %d %8s\n",
     927           0 :                                         ifp->name, group_str,
     928             :                                         grp->igmp_version == 3
     929           0 :                                                 ? (grp->group_filtermode_isexcl
     930             :                                                            ? "EXCL"
     931           0 :                                                            : "INCL")
     932             :                                                 : "----",
     933             :                                         hhmmss,
     934           0 :                                         grp->group_source_list ? listcount(
     935             :                                                 grp->group_source_list)
     936             :                                                                : 0,
     937             :                                         grp->igmp_version, uptime);
     938             :                         }
     939             :                 } /* scan igmp groups */
     940             :         }         /* scan interfaces */
     941             : 
     942           0 :         if (uj)
     943           0 :                 vty_json(vty, json);
     944           0 : }
     945             : 
     946           0 : static void igmp_show_group_retransmission(struct pim_instance *pim,
     947             :                                            struct vty *vty)
     948             : {
     949           0 :         struct interface *ifp;
     950             : 
     951           0 :         vty_out(vty,
     952             :                 "Interface        Group           RetTimer Counter RetSrcs\n");
     953             : 
     954             :         /* scan interfaces */
     955           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
     956           0 :                 struct pim_interface *pim_ifp = ifp->info;
     957           0 :                 struct listnode *grpnode;
     958           0 :                 struct gm_group *grp;
     959             : 
     960           0 :                 if (!pim_ifp)
     961           0 :                         continue;
     962             : 
     963             :                 /* scan igmp groups */
     964           0 :                 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
     965             :                                           grp)) {
     966           0 :                         char group_str[INET_ADDRSTRLEN];
     967           0 :                         char grp_retr_mmss[10];
     968           0 :                         struct listnode *src_node;
     969           0 :                         struct gm_source *src;
     970           0 :                         int grp_retr_sources = 0;
     971             : 
     972           0 :                         pim_inet4_dump("<group?>", grp->group_addr, group_str,
     973             :                                        sizeof(group_str));
     974           0 :                         pim_time_timer_to_mmss(
     975             :                                 grp_retr_mmss, sizeof(grp_retr_mmss),
     976             :                                 grp->t_group_query_retransmit_timer);
     977             : 
     978             : 
     979             :                         /* count group sources with retransmission state
     980             :                          */
     981           0 :                         for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
     982             :                                                   src_node, src)) {
     983           0 :                                 if (src->source_query_retransmit_count > 0) {
     984           0 :                                         ++grp_retr_sources;
     985             :                                 }
     986             :                         }
     987             : 
     988           0 :                         vty_out(vty, "%-16s %-15s %-8s %7d %7d\n", ifp->name,
     989             :                                 group_str, grp_retr_mmss,
     990             :                                 grp->group_specific_query_retransmit_count,
     991             :                                 grp_retr_sources);
     992             : 
     993             :                 } /* scan igmp groups */
     994             :         }         /* scan interfaces */
     995           0 : }
     996             : 
     997           0 : static void igmp_show_sources(struct pim_instance *pim, struct vty *vty,
     998             :                               bool uj)
     999             : {
    1000           0 :         struct interface *ifp;
    1001           0 :         time_t now;
    1002           0 :         json_object *json = NULL;
    1003           0 :         json_object *json_iface = NULL;
    1004           0 :         json_object *json_group = NULL;
    1005           0 :         json_object *json_source = NULL;
    1006           0 :         json_object *json_sources = NULL;
    1007             : 
    1008           0 :         now = pim_time_monotonic_sec();
    1009             : 
    1010           0 :         if (uj)
    1011           0 :                 json = json_object_new_object();
    1012             :         else
    1013           0 :                 vty_out(vty,
    1014             :                         "Interface        Group           Source          Timer Fwd Uptime  \n");
    1015             : 
    1016             :         /* scan interfaces */
    1017           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
    1018           0 :                 struct pim_interface *pim_ifp = ifp->info;
    1019           0 :                 struct listnode *grpnode;
    1020           0 :                 struct gm_group *grp;
    1021             : 
    1022           0 :                 if (!pim_ifp)
    1023           0 :                         continue;
    1024             : 
    1025             :                 /* scan igmp groups */
    1026           0 :                 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
    1027             :                                           grp)) {
    1028           0 :                         char group_str[INET_ADDRSTRLEN];
    1029           0 :                         struct listnode *srcnode;
    1030           0 :                         struct gm_source *src;
    1031             : 
    1032           0 :                         pim_inet4_dump("<group?>", grp->group_addr, group_str,
    1033             :                                        sizeof(group_str));
    1034             : 
    1035             :                         /* scan group sources */
    1036           0 :                         for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
    1037             :                                                   srcnode, src)) {
    1038           0 :                                 char source_str[INET_ADDRSTRLEN];
    1039           0 :                                 char mmss[10];
    1040           0 :                                 char uptime[10];
    1041             : 
    1042           0 :                                 pim_inet4_dump("<source?>", src->source_addr,
    1043             :                                                source_str, sizeof(source_str));
    1044             : 
    1045           0 :                                 pim_time_timer_to_mmss(mmss, sizeof(mmss),
    1046             :                                                        src->t_source_timer);
    1047             : 
    1048           0 :                                 pim_time_uptime(uptime, sizeof(uptime),
    1049           0 :                                                 now - src->source_creation);
    1050             : 
    1051           0 :                                 if (uj) {
    1052           0 :                                         json_object_object_get_ex(
    1053           0 :                                                 json, ifp->name, &json_iface);
    1054           0 :                                         if (!json_iface) {
    1055           0 :                                                 json_iface =
    1056           0 :                                                         json_object_new_object();
    1057           0 :                                                 json_object_string_add(
    1058             :                                                         json_iface, "name",
    1059             :                                                         ifp->name);
    1060           0 :                                                 json_object_object_add(
    1061             :                                                         json, ifp->name,
    1062             :                                                         json_iface);
    1063             :                                         }
    1064           0 :                                         json_object_object_get_ex(json_iface,
    1065             :                                                                   group_str,
    1066             :                                                                   &json_group);
    1067             : 
    1068           0 :                                         if (!json_group) {
    1069           0 :                                                 json_group =
    1070           0 :                                                         json_object_new_object();
    1071           0 :                                                 json_object_string_add(
    1072             :                                                         json_group, "group",
    1073             :                                                         group_str);
    1074           0 :                                                 json_object_object_add(
    1075             :                                                         json_iface, group_str,
    1076             :                                                         json_group);
    1077           0 :                                                 json_sources =
    1078           0 :                                                         json_object_new_array();
    1079           0 :                                                 json_object_object_add(
    1080             :                                                         json_group, "sources",
    1081             :                                                         json_sources);
    1082             :                                         }
    1083           0 :                                         json_source = json_object_new_object();
    1084           0 :                                         json_object_string_add(json_source,
    1085             :                                                                "source",
    1086             :                                                                source_str);
    1087           0 :                                         json_object_string_add(json_source,
    1088             :                                                                "timer", mmss);
    1089           0 :                                         json_object_boolean_add(
    1090             :                                                 json_source, "forwarded",
    1091           0 :                                                 IGMP_SOURCE_TEST_FORWARDING(
    1092             :                                                         src->source_flags));
    1093           0 :                                         json_object_string_add(
    1094             :                                                 json_source, "uptime", uptime);
    1095           0 :                                         json_object_array_add(json_sources,
    1096             :                                                               json_source);
    1097             : 
    1098             :                                 } else {
    1099           0 :                                         vty_out(vty,
    1100             :                                                 "%-16s %-15s %-15s %5s %3s %8s\n",
    1101           0 :                                                 ifp->name, group_str,
    1102             :                                                 source_str, mmss,
    1103           0 :                                                 IGMP_SOURCE_TEST_FORWARDING(
    1104             :                                                         src->source_flags)
    1105             :                                                         ? "Y"
    1106             :                                                         : "N",
    1107             :                                                 uptime);
    1108             :                                 }
    1109             : 
    1110             :                         } /* scan group sources */
    1111             :                 }        /* scan igmp groups */
    1112             :         }                 /* scan interfaces */
    1113           0 :         if (uj)
    1114           0 :                 vty_json(vty, json);
    1115           0 : }
    1116             : 
    1117           0 : static void igmp_show_source_retransmission(struct pim_instance *pim,
    1118             :                                             struct vty *vty)
    1119             : {
    1120           0 :         struct interface *ifp;
    1121             : 
    1122           0 :         vty_out(vty,
    1123             :                 "Interface        Group           Source          Counter\n");
    1124             : 
    1125             :         /* scan interfaces */
    1126           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp) {
    1127           0 :                 struct pim_interface *pim_ifp = ifp->info;
    1128           0 :                 struct listnode *grpnode;
    1129           0 :                 struct gm_group *grp;
    1130             : 
    1131           0 :                 if (!pim_ifp)
    1132           0 :                         continue;
    1133             : 
    1134             :                 /* scan igmp groups */
    1135           0 :                 for (ALL_LIST_ELEMENTS_RO(pim_ifp->gm_group_list, grpnode,
    1136             :                                           grp)) {
    1137           0 :                         char group_str[INET_ADDRSTRLEN];
    1138           0 :                         struct listnode *srcnode;
    1139           0 :                         struct gm_source *src;
    1140             : 
    1141           0 :                         pim_inet4_dump("<group?>", grp->group_addr, group_str,
    1142             :                                        sizeof(group_str));
    1143             : 
    1144             :                         /* scan group sources */
    1145           0 :                         for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
    1146             :                                                   srcnode, src)) {
    1147           0 :                                 char source_str[INET_ADDRSTRLEN];
    1148             : 
    1149           0 :                                 pim_inet4_dump("<source?>", src->source_addr,
    1150             :                                                source_str, sizeof(source_str));
    1151             : 
    1152           0 :                                 vty_out(vty, "%-16s %-15s %-15s %7d\n",
    1153           0 :                                         ifp->name, group_str, source_str,
    1154             :                                         src->source_query_retransmit_count);
    1155             : 
    1156             :                         } /* scan group sources */
    1157             :                 }        /* scan igmp groups */
    1158             :         }                 /* scan interfaces */
    1159           0 : }
    1160             : 
    1161           0 : static void clear_igmp_interfaces(struct pim_instance *pim)
    1162             : {
    1163           0 :         struct interface *ifp;
    1164             : 
    1165           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp)
    1166           0 :                 pim_if_addr_del_all_igmp(ifp);
    1167             : 
    1168           0 :         FOR_ALL_INTERFACES (pim->vrf, ifp)
    1169           0 :                 pim_if_addr_add_all(ifp);
    1170           0 : }
    1171             : 
    1172           0 : static void clear_interfaces(struct pim_instance *pim)
    1173             : {
    1174           0 :         clear_igmp_interfaces(pim);
    1175           0 :         clear_pim_interfaces(pim);
    1176             : }
    1177             : 
    1178             : #define PIM_GET_PIM_INTERFACE(pim_ifp, ifp)                             \
    1179             :         pim_ifp = ifp->info;                                         \
    1180             :         if (!pim_ifp) {                                                 \
    1181             :                 vty_out(vty,                                            \
    1182             :                         "%% Enable PIM and/or IGMP on this interface first\n"); \
    1183             :                 return CMD_WARNING_CONFIG_FAILED;                       \
    1184             :         }
    1185             : 
    1186             : /**
    1187             :  * Compatibility function to keep the legacy mesh group CLI behavior:
    1188             :  * Delete group when there are no more configurations in it.
    1189             :  *
    1190             :  * NOTE:
    1191             :  * Don't forget to call `nb_cli_apply_changes` after this.
    1192             :  */
    1193           0 : static void pim_cli_legacy_mesh_group_behavior(struct vty *vty,
    1194             :                                                const char *gname)
    1195             : {
    1196           0 :         const char *vrfname;
    1197           0 :         char xpath_value[XPATH_MAXLEN];
    1198           0 :         char xpath_member_value[XPATH_MAXLEN];
    1199           0 :         const struct lyd_node *member_dnode;
    1200             : 
    1201           0 :         vrfname = pim_cli_get_vrf_name(vty);
    1202           0 :         if (vrfname == NULL)
    1203           0 :                 return;
    1204             : 
    1205             :         /* Get mesh group base XPath. */
    1206           0 :         snprintf(xpath_value, sizeof(xpath_value),
    1207             :                  FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
    1208             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
    1209             :         /* Group must exists, otherwise just quit. */
    1210           0 :         if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
    1211             :                 return;
    1212             : 
    1213             :         /* Group members check: */
    1214           0 :         strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
    1215           0 :         strlcat(xpath_member_value, "/members", sizeof(xpath_member_value));
    1216           0 :         if (yang_dnode_exists(vty->candidate_config->dnode,
    1217             :                               xpath_member_value)) {
    1218           0 :                 member_dnode = yang_dnode_get(vty->candidate_config->dnode,
    1219             :                                               xpath_member_value);
    1220           0 :                 if (!member_dnode || !yang_is_last_list_dnode(member_dnode))
    1221           0 :                         return;
    1222             :         }
    1223             : 
    1224             :         /* Source address check: */
    1225           0 :         strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
    1226           0 :         strlcat(xpath_member_value, "/source", sizeof(xpath_member_value));
    1227           0 :         if (yang_dnode_exists(vty->candidate_config->dnode, xpath_member_value))
    1228             :                 return;
    1229             : 
    1230             :         /* No configurations found: delete it. */
    1231           0 :         nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
    1232             : }
    1233             : 
    1234           0 : DEFUN (clear_ip_interfaces,
    1235             :        clear_ip_interfaces_cmd,
    1236             :        "clear ip interfaces [vrf NAME]",
    1237             :        CLEAR_STR
    1238             :        IP_STR
    1239             :        "Reset interfaces\n"
    1240             :        VRF_CMD_HELP_STR)
    1241             : {
    1242           0 :         int idx = 2;
    1243           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1244             : 
    1245           0 :         if (!vrf)
    1246             :                 return CMD_WARNING;
    1247             : 
    1248           0 :         clear_interfaces(vrf->info);
    1249             : 
    1250           0 :         return CMD_SUCCESS;
    1251             : }
    1252             : 
    1253           0 : DEFUN (clear_ip_igmp_interfaces,
    1254             :        clear_ip_igmp_interfaces_cmd,
    1255             :        "clear ip igmp [vrf NAME] interfaces",
    1256             :        CLEAR_STR
    1257             :        IP_STR
    1258             :        CLEAR_IP_IGMP_STR
    1259             :        VRF_CMD_HELP_STR
    1260             :        "Reset IGMP interfaces\n")
    1261             : {
    1262           0 :         int idx = 2;
    1263           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1264             : 
    1265           0 :         if (!vrf)
    1266             :                 return CMD_WARNING;
    1267             : 
    1268           0 :         clear_igmp_interfaces(vrf->info);
    1269             : 
    1270           0 :         return CMD_SUCCESS;
    1271             : }
    1272             : 
    1273           0 : DEFPY (clear_ip_pim_statistics,
    1274             :        clear_ip_pim_statistics_cmd,
    1275             :        "clear ip pim statistics [vrf NAME]$name",
    1276             :        CLEAR_STR
    1277             :        IP_STR
    1278             :        CLEAR_IP_PIM_STR
    1279             :        VRF_CMD_HELP_STR
    1280             :        "Reset PIM statistics\n")
    1281             : {
    1282           0 :         struct vrf *v = pim_cmd_lookup(vty, name);
    1283             : 
    1284           0 :         if (!v)
    1285             :                 return CMD_WARNING;
    1286             : 
    1287           0 :         clear_pim_statistics(v->info);
    1288             : 
    1289           0 :         return CMD_SUCCESS;
    1290             : }
    1291             : 
    1292           0 : DEFPY (clear_ip_mroute,
    1293             :        clear_ip_mroute_cmd,
    1294             :        "clear ip mroute [vrf NAME]$name",
    1295             :        CLEAR_STR
    1296             :        IP_STR
    1297             :        MROUTE_STR
    1298             :        VRF_CMD_HELP_STR)
    1299             : {
    1300           0 :         struct vrf *v = pim_cmd_lookup(vty, name);
    1301             : 
    1302           0 :         if (!v)
    1303             :                 return CMD_WARNING;
    1304             : 
    1305           0 :         clear_mroute(v->info);
    1306             : 
    1307           0 :         return CMD_SUCCESS;
    1308             : }
    1309             : 
    1310           0 : DEFPY (clear_ip_pim_interfaces,
    1311             :        clear_ip_pim_interfaces_cmd,
    1312             :        "clear ip pim [vrf NAME] interfaces",
    1313             :        CLEAR_STR
    1314             :        IP_STR
    1315             :        CLEAR_IP_PIM_STR
    1316             :        VRF_CMD_HELP_STR
    1317             :        "Reset PIM interfaces\n")
    1318             : {
    1319           0 :         struct vrf *v = pim_cmd_lookup(vty, vrf);
    1320             : 
    1321           0 :         if (!v)
    1322             :                 return CMD_WARNING;
    1323             : 
    1324           0 :         clear_pim_interfaces(v->info);
    1325             : 
    1326           0 :         return CMD_SUCCESS;
    1327             : }
    1328             : 
    1329           0 : DEFPY (clear_ip_pim_interface_traffic,
    1330             :        clear_ip_pim_interface_traffic_cmd,
    1331             :        "clear ip pim [vrf NAME] interface traffic",
    1332             :        CLEAR_STR
    1333             :        IP_STR
    1334             :        CLEAR_IP_PIM_STR
    1335             :        VRF_CMD_HELP_STR
    1336             :        "Reset PIM interfaces\n"
    1337             :        "Reset Protocol Packet counters\n")
    1338             : {
    1339           0 :         return clear_pim_interface_traffic(vrf, vty);
    1340             : }
    1341             : 
    1342           0 : DEFPY (clear_ip_pim_oil,
    1343             :        clear_ip_pim_oil_cmd,
    1344             :        "clear ip pim [vrf NAME]$name oil",
    1345             :        CLEAR_STR
    1346             :        IP_STR
    1347             :        CLEAR_IP_PIM_STR
    1348             :        VRF_CMD_HELP_STR
    1349             :        "Rescan PIM OIL (output interface list)\n")
    1350             : {
    1351           0 :         struct vrf *v = pim_cmd_lookup(vty, name);
    1352             : 
    1353           0 :         if (!v)
    1354             :                 return CMD_WARNING;
    1355             : 
    1356           0 :         pim_scan_oil(v->info);
    1357             : 
    1358           0 :         return CMD_SUCCESS;
    1359             : }
    1360             : 
    1361           0 : DEFUN (clear_ip_pim_bsr_db,
    1362             :        clear_ip_pim_bsr_db_cmd,
    1363             :        "clear ip pim [vrf NAME] bsr-data",
    1364             :        CLEAR_STR
    1365             :        IP_STR
    1366             :        CLEAR_IP_PIM_STR
    1367             :        VRF_CMD_HELP_STR
    1368             :        "Reset pim bsr data\n")
    1369             : {
    1370           0 :         int idx = 2;
    1371           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1372             : 
    1373           0 :         if (!vrf)
    1374             :                 return CMD_WARNING;
    1375             : 
    1376           0 :         pim_bsm_clear(vrf->info);
    1377             : 
    1378           0 :         return CMD_SUCCESS;
    1379             : }
    1380             : 
    1381           0 : DEFUN (show_ip_igmp_interface,
    1382             :        show_ip_igmp_interface_cmd,
    1383             :        "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
    1384             :        SHOW_STR
    1385             :        IP_STR
    1386             :        IGMP_STR
    1387             :        VRF_CMD_HELP_STR
    1388             :        "IGMP interface information\n"
    1389             :        "Detailed output\n"
    1390             :        "interface name\n"
    1391             :        JSON_STR)
    1392             : {
    1393           0 :         int idx = 2;
    1394           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1395           0 :         bool uj = use_json(argc, argv);
    1396             : 
    1397           0 :         if (!vrf)
    1398             :                 return CMD_WARNING;
    1399             : 
    1400           0 :         if (argv_find(argv, argc, "detail", &idx)
    1401           0 :             || argv_find(argv, argc, "WORD", &idx))
    1402           0 :                 igmp_show_interfaces_single(vrf->info, vty, argv[idx]->arg, uj);
    1403             :         else
    1404           0 :                 igmp_show_interfaces(vrf->info, vty, uj);
    1405             : 
    1406             :         return CMD_SUCCESS;
    1407             : }
    1408             : 
    1409           0 : DEFUN (show_ip_igmp_interface_vrf_all,
    1410             :        show_ip_igmp_interface_vrf_all_cmd,
    1411             :        "show ip igmp vrf all interface [detail|WORD] [json]",
    1412             :        SHOW_STR
    1413             :        IP_STR
    1414             :        IGMP_STR
    1415             :        VRF_CMD_HELP_STR
    1416             :        "IGMP interface information\n"
    1417             :        "Detailed output\n"
    1418             :        "interface name\n"
    1419             :        JSON_STR)
    1420             : {
    1421           0 :         int idx = 2;
    1422           0 :         bool uj = use_json(argc, argv);
    1423           0 :         struct vrf *vrf;
    1424           0 :         bool first = true;
    1425             : 
    1426           0 :         if (uj)
    1427           0 :                 vty_out(vty, "{ ");
    1428           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    1429           0 :                 if (uj) {
    1430           0 :                         if (!first)
    1431           0 :                                 vty_out(vty, ", ");
    1432           0 :                         vty_out(vty, " \"%s\": ", vrf->name);
    1433           0 :                         first = false;
    1434             :                 } else
    1435           0 :                         vty_out(vty, "VRF: %s\n", vrf->name);
    1436           0 :                 if (argv_find(argv, argc, "detail", &idx)
    1437           0 :                     || argv_find(argv, argc, "WORD", &idx))
    1438           0 :                         igmp_show_interfaces_single(vrf->info, vty,
    1439           0 :                                                     argv[idx]->arg, uj);
    1440             :                 else
    1441           0 :                         igmp_show_interfaces(vrf->info, vty, uj);
    1442             :         }
    1443           0 :         if (uj)
    1444           0 :                 vty_out(vty, "}\n");
    1445             : 
    1446           0 :         return CMD_SUCCESS;
    1447             : }
    1448             : 
    1449           0 : DEFUN (show_ip_igmp_join,
    1450             :        show_ip_igmp_join_cmd,
    1451             :        "show ip igmp [vrf NAME] join [json]",
    1452             :        SHOW_STR
    1453             :        IP_STR
    1454             :        IGMP_STR
    1455             :        VRF_CMD_HELP_STR
    1456             :        "IGMP static join information\n"
    1457             :        JSON_STR)
    1458             : {
    1459           0 :         int idx = 2;
    1460           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1461           0 :         bool uj = use_json(argc, argv);
    1462             : 
    1463           0 :         if (!vrf)
    1464             :                 return CMD_WARNING;
    1465             : 
    1466           0 :         igmp_show_interface_join(vrf->info, vty, uj);
    1467             : 
    1468           0 :         return CMD_SUCCESS;
    1469             : }
    1470             : 
    1471           0 : DEFUN (show_ip_igmp_join_vrf_all,
    1472             :        show_ip_igmp_join_vrf_all_cmd,
    1473             :        "show ip igmp vrf all join [json]",
    1474             :        SHOW_STR
    1475             :        IP_STR
    1476             :        IGMP_STR
    1477             :        VRF_CMD_HELP_STR
    1478             :        "IGMP static join information\n"
    1479             :        JSON_STR)
    1480             : {
    1481           0 :         bool uj = use_json(argc, argv);
    1482           0 :         struct vrf *vrf;
    1483           0 :         bool first = true;
    1484             : 
    1485           0 :         if (uj)
    1486           0 :                 vty_out(vty, "{ ");
    1487           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    1488           0 :                 if (uj) {
    1489           0 :                         if (!first)
    1490           0 :                                 vty_out(vty, ", ");
    1491           0 :                         vty_out(vty, " \"%s\": ", vrf->name);
    1492           0 :                         first = false;
    1493             :                 } else
    1494           0 :                         vty_out(vty, "VRF: %s\n", vrf->name);
    1495           0 :                 igmp_show_interface_join(vrf->info, vty, uj);
    1496             :         }
    1497           0 :         if (uj)
    1498           0 :                 vty_out(vty, "}\n");
    1499             : 
    1500           0 :         return CMD_SUCCESS;
    1501             : }
    1502             : 
    1503           0 : DEFUN (show_ip_igmp_groups,
    1504             :        show_ip_igmp_groups_cmd,
    1505             :        "show ip igmp [vrf NAME] groups [json]",
    1506             :        SHOW_STR
    1507             :        IP_STR
    1508             :        IGMP_STR
    1509             :        VRF_CMD_HELP_STR
    1510             :        IGMP_GROUP_STR
    1511             :        JSON_STR)
    1512             : {
    1513           0 :         int idx = 2;
    1514           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1515           0 :         bool uj = use_json(argc, argv);
    1516             : 
    1517           0 :         if (!vrf)
    1518             :                 return CMD_WARNING;
    1519             : 
    1520           0 :         igmp_show_groups(vrf->info, vty, uj);
    1521             : 
    1522           0 :         return CMD_SUCCESS;
    1523             : }
    1524             : 
    1525           0 : DEFUN (show_ip_igmp_groups_vrf_all,
    1526             :        show_ip_igmp_groups_vrf_all_cmd,
    1527             :        "show ip igmp vrf all groups [json]",
    1528             :        SHOW_STR
    1529             :        IP_STR
    1530             :        IGMP_STR
    1531             :        VRF_CMD_HELP_STR
    1532             :        IGMP_GROUP_STR
    1533             :        JSON_STR)
    1534             : {
    1535           0 :         bool uj = use_json(argc, argv);
    1536           0 :         struct vrf *vrf;
    1537           0 :         bool first = true;
    1538             : 
    1539           0 :         if (uj)
    1540           0 :                 vty_out(vty, "{ ");
    1541           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    1542           0 :                 if (uj) {
    1543           0 :                         if (!first)
    1544           0 :                                 vty_out(vty, ", ");
    1545           0 :                         vty_out(vty, " \"%s\": ", vrf->name);
    1546           0 :                         first = false;
    1547             :                 } else
    1548           0 :                         vty_out(vty, "VRF: %s\n", vrf->name);
    1549           0 :                 igmp_show_groups(vrf->info, vty, uj);
    1550             :         }
    1551           0 :         if (uj)
    1552           0 :                 vty_out(vty, "}\n");
    1553             : 
    1554           0 :         return CMD_SUCCESS;
    1555             : }
    1556             : 
    1557           0 : DEFUN (show_ip_igmp_groups_retransmissions,
    1558             :        show_ip_igmp_groups_retransmissions_cmd,
    1559             :        "show ip igmp [vrf NAME] groups retransmissions",
    1560             :        SHOW_STR
    1561             :        IP_STR
    1562             :        IGMP_STR
    1563             :        VRF_CMD_HELP_STR
    1564             :        IGMP_GROUP_STR
    1565             :        "IGMP group retransmissions\n")
    1566             : {
    1567           0 :         int idx = 2;
    1568           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1569             : 
    1570           0 :         if (!vrf)
    1571             :                 return CMD_WARNING;
    1572             : 
    1573           0 :         igmp_show_group_retransmission(vrf->info, vty);
    1574             : 
    1575           0 :         return CMD_SUCCESS;
    1576             : }
    1577             : 
    1578           0 : DEFUN (show_ip_igmp_sources,
    1579             :        show_ip_igmp_sources_cmd,
    1580             :        "show ip igmp [vrf NAME] sources [json]",
    1581             :        SHOW_STR
    1582             :        IP_STR
    1583             :        IGMP_STR
    1584             :        VRF_CMD_HELP_STR
    1585             :        IGMP_SOURCE_STR
    1586             :        JSON_STR)
    1587             : {
    1588           0 :         int idx = 2;
    1589           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1590             : 
    1591           0 :         if (!vrf)
    1592             :                 return CMD_WARNING;
    1593             : 
    1594           0 :         igmp_show_sources(vrf->info, vty, use_json(argc, argv));
    1595             : 
    1596           0 :         return CMD_SUCCESS;
    1597             : }
    1598             : 
    1599           0 : DEFUN (show_ip_igmp_sources_retransmissions,
    1600             :        show_ip_igmp_sources_retransmissions_cmd,
    1601             :        "show ip igmp [vrf NAME] sources retransmissions",
    1602             :        SHOW_STR
    1603             :        IP_STR
    1604             :        IGMP_STR
    1605             :        VRF_CMD_HELP_STR
    1606             :        IGMP_SOURCE_STR
    1607             :        "IGMP source retransmissions\n")
    1608             : {
    1609           0 :         int idx = 2;
    1610           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1611             : 
    1612           0 :         if (!vrf)
    1613             :                 return CMD_WARNING;
    1614             : 
    1615           0 :         igmp_show_source_retransmission(vrf->info, vty);
    1616             : 
    1617           0 :         return CMD_SUCCESS;
    1618             : }
    1619             : 
    1620           0 : DEFUN (show_ip_igmp_statistics,
    1621             :        show_ip_igmp_statistics_cmd,
    1622             :        "show ip igmp [vrf NAME] statistics [interface WORD] [json]",
    1623             :        SHOW_STR
    1624             :        IP_STR
    1625             :        IGMP_STR
    1626             :        VRF_CMD_HELP_STR
    1627             :        "IGMP statistics\n"
    1628             :        "interface\n"
    1629             :        "IGMP interface\n"
    1630             :        JSON_STR)
    1631             : {
    1632           0 :         int idx = 2;
    1633           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1634           0 :         bool uj = use_json(argc, argv);
    1635             : 
    1636           0 :         if (!vrf)
    1637             :                 return CMD_WARNING;
    1638             : 
    1639           0 :         if (argv_find(argv, argc, "WORD", &idx))
    1640           0 :                 igmp_show_statistics(vrf->info, vty, argv[idx]->arg, uj);
    1641             :         else
    1642           0 :                 igmp_show_statistics(vrf->info, vty, NULL, uj);
    1643             : 
    1644             :         return CMD_SUCCESS;
    1645             : }
    1646             : 
    1647           0 : DEFUN (show_ip_pim_mlag_summary,
    1648             :        show_ip_pim_mlag_summary_cmd,
    1649             :        "show ip pim mlag summary [json]",
    1650             :        SHOW_STR
    1651             :        IP_STR
    1652             :        PIM_STR
    1653             :        "MLAG\n"
    1654             :        "status and stats\n"
    1655             :        JSON_STR)
    1656             : {
    1657           0 :         bool uj = use_json(argc, argv);
    1658           0 :         char role_buf[MLAG_ROLE_STRSIZE];
    1659           0 :         char addr_buf[INET_ADDRSTRLEN];
    1660             : 
    1661           0 :         if (uj) {
    1662           0 :                 json_object *json = NULL;
    1663           0 :                 json_object *json_stat = NULL;
    1664             : 
    1665           0 :                 json = json_object_new_object();
    1666           0 :                 if (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
    1667           0 :                         json_object_boolean_true_add(json, "mlagConnUp");
    1668           0 :                 if (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
    1669           0 :                         json_object_boolean_true_add(json, "mlagPeerConnUp");
    1670           0 :                 if (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
    1671           0 :                         json_object_boolean_true_add(json, "mlagPeerZebraUp");
    1672           0 :                 json_object_string_add(json, "mlagRole",
    1673           0 :                                        mlag_role2str(router->mlag_role,
    1674             :                                                      role_buf, sizeof(role_buf)));
    1675           0 :                 inet_ntop(AF_INET, &router->local_vtep_ip,
    1676             :                           addr_buf, INET_ADDRSTRLEN);
    1677           0 :                 json_object_string_add(json, "localVtepIp", addr_buf);
    1678           0 :                 inet_ntop(AF_INET, &router->anycast_vtep_ip,
    1679             :                           addr_buf, INET_ADDRSTRLEN);
    1680           0 :                 json_object_string_add(json, "anycastVtepIp", addr_buf);
    1681           0 :                 json_object_string_add(json, "peerlinkRif",
    1682           0 :                                        router->peerlink_rif);
    1683             : 
    1684           0 :                 json_stat = json_object_new_object();
    1685           0 :                 json_object_int_add(json_stat, "mlagConnFlaps",
    1686           0 :                                     router->mlag_stats.mlagd_session_downs);
    1687           0 :                 json_object_int_add(json_stat, "mlagPeerConnFlaps",
    1688           0 :                                     router->mlag_stats.peer_session_downs);
    1689           0 :                 json_object_int_add(json_stat, "mlagPeerZebraFlaps",
    1690           0 :                                     router->mlag_stats.peer_zebra_downs);
    1691           0 :                 json_object_int_add(json_stat, "mrouteAddRx",
    1692           0 :                                     router->mlag_stats.msg.mroute_add_rx);
    1693           0 :                 json_object_int_add(json_stat, "mrouteAddTx",
    1694           0 :                                     router->mlag_stats.msg.mroute_add_tx);
    1695           0 :                 json_object_int_add(json_stat, "mrouteDelRx",
    1696           0 :                                     router->mlag_stats.msg.mroute_del_rx);
    1697           0 :                 json_object_int_add(json_stat, "mrouteDelTx",
    1698           0 :                                     router->mlag_stats.msg.mroute_del_tx);
    1699           0 :                 json_object_int_add(json_stat, "mlagStatusUpdates",
    1700           0 :                                     router->mlag_stats.msg.mlag_status_updates);
    1701           0 :                 json_object_int_add(json_stat, "peerZebraStatusUpdates",
    1702           0 :                                     router->mlag_stats.msg.peer_zebra_status_updates);
    1703           0 :                 json_object_int_add(json_stat, "pimStatusUpdates",
    1704           0 :                                     router->mlag_stats.msg.pim_status_updates);
    1705           0 :                 json_object_int_add(json_stat, "vxlanUpdates",
    1706           0 :                                     router->mlag_stats.msg.vxlan_updates);
    1707           0 :                 json_object_object_add(json, "connStats", json_stat);
    1708             : 
    1709           0 :                 vty_json(vty, json);
    1710           0 :                 return CMD_SUCCESS;
    1711             :         }
    1712             : 
    1713           0 :         vty_out(vty, "MLAG daemon connection: %s\n",
    1714           0 :                 (router->mlag_flags & PIM_MLAGF_LOCAL_CONN_UP)
    1715             :                 ? "up" : "down");
    1716           0 :         vty_out(vty, "MLAG peer state: %s\n",
    1717           0 :                 (router->mlag_flags & PIM_MLAGF_PEER_CONN_UP)
    1718             :                 ? "up" : "down");
    1719           0 :         vty_out(vty, "Zebra peer state: %s\n",
    1720           0 :                 (router->mlag_flags & PIM_MLAGF_PEER_ZEBRA_UP)
    1721             :                 ? "up" : "down");
    1722           0 :         vty_out(vty, "MLAG role: %s\n",
    1723           0 :                 mlag_role2str(router->mlag_role, role_buf, sizeof(role_buf)));
    1724           0 :         inet_ntop(AF_INET, &router->local_vtep_ip,
    1725             :                   addr_buf, INET_ADDRSTRLEN);
    1726           0 :         vty_out(vty, "Local VTEP IP: %s\n", addr_buf);
    1727           0 :         inet_ntop(AF_INET, &router->anycast_vtep_ip,
    1728             :                   addr_buf, INET_ADDRSTRLEN);
    1729           0 :         vty_out(vty, "Anycast VTEP IP: %s\n", addr_buf);
    1730           0 :         vty_out(vty, "Peerlink: %s\n", router->peerlink_rif);
    1731           0 :         vty_out(vty, "Session flaps: mlagd: %d mlag-peer: %d zebra-peer: %d\n",
    1732             :                 router->mlag_stats.mlagd_session_downs,
    1733             :                 router->mlag_stats.peer_session_downs,
    1734           0 :                 router->mlag_stats.peer_zebra_downs);
    1735           0 :         vty_out(vty, "Message Statistics:\n");
    1736           0 :         vty_out(vty, "  mroute adds: rx: %d, tx: %d\n",
    1737             :                 router->mlag_stats.msg.mroute_add_rx,
    1738           0 :                 router->mlag_stats.msg.mroute_add_tx);
    1739           0 :         vty_out(vty, "  mroute dels: rx: %d, tx: %d\n",
    1740             :                 router->mlag_stats.msg.mroute_del_rx,
    1741           0 :                 router->mlag_stats.msg.mroute_del_tx);
    1742           0 :         vty_out(vty, "  peer zebra status updates: %d\n",
    1743           0 :                 router->mlag_stats.msg.peer_zebra_status_updates);
    1744           0 :         vty_out(vty, "  PIM status updates: %d\n",
    1745           0 :                 router->mlag_stats.msg.pim_status_updates);
    1746           0 :         vty_out(vty, "  VxLAN updates: %d\n",
    1747           0 :                 router->mlag_stats.msg.vxlan_updates);
    1748             : 
    1749           0 :         return CMD_SUCCESS;
    1750             : }
    1751             : 
    1752           0 : DEFUN (show_ip_pim_assert,
    1753             :        show_ip_pim_assert_cmd,
    1754             :        "show ip pim [vrf NAME] assert",
    1755             :        SHOW_STR
    1756             :        IP_STR
    1757             :        PIM_STR
    1758             :        VRF_CMD_HELP_STR
    1759             :        "PIM interface assert\n")
    1760             : {
    1761           0 :         int idx = 2;
    1762           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1763             : 
    1764           0 :         if (!vrf)
    1765             :                 return CMD_WARNING;
    1766             : 
    1767           0 :         pim_show_assert(vrf->info, vty);
    1768             : 
    1769           0 :         return CMD_SUCCESS;
    1770             : }
    1771             : 
    1772           0 : DEFUN (show_ip_pim_assert_internal,
    1773             :        show_ip_pim_assert_internal_cmd,
    1774             :        "show ip pim [vrf NAME] assert-internal",
    1775             :        SHOW_STR
    1776             :        IP_STR
    1777             :        PIM_STR
    1778             :        VRF_CMD_HELP_STR
    1779             :        "PIM interface internal assert state\n")
    1780             : {
    1781           0 :         int idx = 2;
    1782           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1783             : 
    1784           0 :         if (!vrf)
    1785             :                 return CMD_WARNING;
    1786             : 
    1787           0 :         pim_show_assert_internal(vrf->info, vty);
    1788             : 
    1789           0 :         return CMD_SUCCESS;
    1790             : }
    1791             : 
    1792           0 : DEFUN (show_ip_pim_assert_metric,
    1793             :        show_ip_pim_assert_metric_cmd,
    1794             :        "show ip pim [vrf NAME] assert-metric",
    1795             :        SHOW_STR
    1796             :        IP_STR
    1797             :        PIM_STR
    1798             :        VRF_CMD_HELP_STR
    1799             :        "PIM interface assert metric\n")
    1800             : {
    1801           0 :         int idx = 2;
    1802           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1803             : 
    1804           0 :         if (!vrf)
    1805             :                 return CMD_WARNING;
    1806             : 
    1807           0 :         pim_show_assert_metric(vrf->info, vty);
    1808             : 
    1809           0 :         return CMD_SUCCESS;
    1810             : }
    1811             : 
    1812           0 : DEFUN (show_ip_pim_assert_winner_metric,
    1813             :        show_ip_pim_assert_winner_metric_cmd,
    1814             :        "show ip pim [vrf NAME] assert-winner-metric",
    1815             :        SHOW_STR
    1816             :        IP_STR
    1817             :        PIM_STR
    1818             :        VRF_CMD_HELP_STR
    1819             :        "PIM interface assert winner metric\n")
    1820             : {
    1821           0 :         int idx = 2;
    1822           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    1823             : 
    1824           0 :         if (!vrf)
    1825             :                 return CMD_WARNING;
    1826             : 
    1827           0 :         pim_show_assert_winner_metric(vrf->info, vty);
    1828             : 
    1829           0 :         return CMD_SUCCESS;
    1830             : }
    1831             : 
    1832           0 : DEFPY (show_ip_pim_interface,
    1833             :        show_ip_pim_interface_cmd,
    1834             :        "show ip pim [mlag$mlag] [vrf NAME] interface [detail|WORD]$interface [json$json]",
    1835             :        SHOW_STR
    1836             :        IP_STR
    1837             :        PIM_STR
    1838             :        "MLAG\n"
    1839             :        VRF_CMD_HELP_STR
    1840             :        "PIM interface information\n"
    1841             :        "Detailed output\n"
    1842             :        "interface name\n"
    1843             :        JSON_STR)
    1844             : {
    1845           0 :         return pim_show_interface_cmd_helper(vrf, vty, !!json, !!mlag,
    1846             :                                              interface);
    1847             : }
    1848             : 
    1849           0 : DEFPY (show_ip_pim_interface_vrf_all,
    1850             :        show_ip_pim_interface_vrf_all_cmd,
    1851             :        "show ip pim [mlag$mlag] vrf all interface [detail|WORD]$interface [json$json]",
    1852             :        SHOW_STR
    1853             :        IP_STR
    1854             :        PIM_STR
    1855             :        "MLAG\n"
    1856             :        VRF_CMD_HELP_STR
    1857             :        "PIM interface information\n"
    1858             :        "Detailed output\n"
    1859             :        "interface name\n"
    1860             :        JSON_STR)
    1861             : {
    1862           0 :         return pim_show_interface_vrf_all_cmd_helper(vty, !!json, !!mlag,
    1863             :                                                      interface);
    1864             : }
    1865             : 
    1866           0 : DEFPY (show_ip_pim_join,
    1867             :        show_ip_pim_join_cmd,
    1868             :        "show ip pim [vrf NAME] join [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
    1869             :        SHOW_STR
    1870             :        IP_STR
    1871             :        PIM_STR
    1872             :        VRF_CMD_HELP_STR
    1873             :        "PIM interface join information\n"
    1874             :        "The Source or Group\n"
    1875             :        "The Group\n"
    1876             :        JSON_STR)
    1877             : {
    1878           0 :         return pim_show_join_cmd_helper(vrf, vty, s_or_g, g, json);
    1879             : }
    1880             : 
    1881           0 : DEFPY (show_ip_pim_join_vrf_all,
    1882             :        show_ip_pim_join_vrf_all_cmd,
    1883             :        "show ip pim vrf all join [json$json]",
    1884             :        SHOW_STR
    1885             :        IP_STR
    1886             :        PIM_STR
    1887             :        VRF_CMD_HELP_STR
    1888             :        "PIM interface join information\n"
    1889             :        JSON_STR)
    1890             : {
    1891           0 :         return pim_show_join_vrf_all_cmd_helper(vty, json);
    1892             : }
    1893             : 
    1894           0 : DEFPY (show_ip_pim_jp_agg,
    1895             :        show_ip_pim_jp_agg_cmd,
    1896             :        "show ip pim [vrf NAME] jp-agg",
    1897             :        SHOW_STR
    1898             :        IP_STR
    1899             :        PIM_STR
    1900             :        VRF_CMD_HELP_STR
    1901             :        "join prune aggregation list\n")
    1902             : {
    1903           0 :         return pim_show_jp_agg_list_cmd_helper(vrf, vty);
    1904             : }
    1905             : 
    1906           0 : DEFPY (show_ip_pim_local_membership,
    1907             :        show_ip_pim_local_membership_cmd,
    1908             :        "show ip pim [vrf NAME] local-membership [json$json]",
    1909             :        SHOW_STR
    1910             :        IP_STR
    1911             :        PIM_STR
    1912             :        VRF_CMD_HELP_STR
    1913             :        "PIM interface local-membership\n"
    1914             :        JSON_STR)
    1915             : {
    1916           0 :         return pim_show_membership_cmd_helper(vrf, vty, !!json);
    1917             : }
    1918             : 
    1919           0 : static void pim_show_mlag_up_entry_detail(struct vrf *vrf,
    1920             :                                           struct vty *vty,
    1921             :                                           struct pim_upstream *up,
    1922             :                                           char *src_str, char *grp_str,
    1923             :                                           json_object *json)
    1924             : {
    1925           0 :         if (json) {
    1926           0 :                 json_object *json_row = NULL;
    1927           0 :                 json_object *own_list = NULL;
    1928           0 :                 json_object *json_group = NULL;
    1929             : 
    1930             : 
    1931           0 :                 json_object_object_get_ex(json, grp_str, &json_group);
    1932           0 :                 if (!json_group) {
    1933           0 :                         json_group = json_object_new_object();
    1934           0 :                         json_object_object_add(json, grp_str,
    1935             :                                                json_group);
    1936             :                 }
    1937             : 
    1938           0 :                 json_row = json_object_new_object();
    1939           0 :                 json_object_string_add(json_row, "source", src_str);
    1940           0 :                 json_object_string_add(json_row, "group", grp_str);
    1941             : 
    1942           0 :                 own_list = json_object_new_array();
    1943           0 :                 if (pim_up_mlag_is_local(up))
    1944           0 :                         json_object_array_add(own_list,
    1945             :                                               json_object_new_string("local"));
    1946           0 :                 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
    1947           0 :                         json_object_array_add(own_list,
    1948             :                                               json_object_new_string("peer"));
    1949           0 :                 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
    1950           0 :                         json_object_array_add(
    1951             :                                 own_list, json_object_new_string("Interface"));
    1952           0 :                 json_object_object_add(json_row, "owners", own_list);
    1953             : 
    1954           0 :                 json_object_int_add(json_row, "localCost",
    1955           0 :                                     pim_up_mlag_local_cost(up));
    1956           0 :                 json_object_int_add(json_row, "peerCost",
    1957           0 :                                     pim_up_mlag_peer_cost(up));
    1958           0 :                 if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
    1959           0 :                         json_object_boolean_false_add(json_row, "df");
    1960             :                 else
    1961           0 :                         json_object_boolean_true_add(json_row, "df");
    1962           0 :                 json_object_object_add(json_group, src_str, json_row);
    1963             :         } else {
    1964           0 :                 char own_str[6];
    1965             : 
    1966           0 :                 own_str[0] = '\0';
    1967           0 :                 if (pim_up_mlag_is_local(up))
    1968           0 :                         strlcat(own_str, "L", sizeof(own_str));
    1969           0 :                 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
    1970           0 :                         strlcat(own_str, "P", sizeof(own_str));
    1971           0 :                 if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
    1972           0 :                         strlcat(own_str, "I", sizeof(own_str));
    1973             :                 /* XXX - fixup, print paragraph output */
    1974           0 :                 vty_out(vty,
    1975             :                         "%-15s %-15s %-6s %-11u %-10d %2s\n",
    1976             :                         src_str, grp_str, own_str,
    1977             :                         pim_up_mlag_local_cost(up),
    1978             :                         pim_up_mlag_peer_cost(up),
    1979           0 :                         PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
    1980             :                         ? "n" : "y");
    1981             :         }
    1982           0 : }
    1983             : 
    1984           0 : static void pim_show_mlag_up_detail(struct vrf *vrf,
    1985             :                                     struct vty *vty, const char *src_or_group,
    1986             :                                     const char *group, bool uj)
    1987             : {
    1988           0 :         char src_str[PIM_ADDRSTRLEN];
    1989           0 :         char grp_str[PIM_ADDRSTRLEN];
    1990           0 :         struct pim_upstream *up;
    1991           0 :         struct pim_instance *pim = vrf->info;
    1992           0 :         json_object *json = NULL;
    1993             : 
    1994           0 :         if (uj)
    1995           0 :                 json = json_object_new_object();
    1996             :         else
    1997           0 :                 vty_out(vty,
    1998             :                         "Source          Group           Owner  Local-cost  Peer-cost  DF\n");
    1999             : 
    2000           0 :         frr_each (rb_pim_upstream, &pim->upstream_head, up) {
    2001           0 :                 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
    2002           0 :                     && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
    2003           0 :                     && !pim_up_mlag_is_local(up))
    2004           0 :                         continue;
    2005             : 
    2006           0 :                 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &up->sg.grp);
    2007           0 :                 snprintfrr(src_str, sizeof(src_str), "%pPAs", &up->sg.src);
    2008             : 
    2009             :                 /* XXX: strcmps are clearly inefficient. we should do uint comps
    2010             :                  * here instead.
    2011             :                  */
    2012           0 :                 if (group) {
    2013           0 :                         if (strcmp(src_str, src_or_group) ||
    2014           0 :                             strcmp(grp_str, group))
    2015           0 :                                 continue;
    2016             :                 } else {
    2017           0 :                         if (strcmp(src_str, src_or_group) &&
    2018           0 :                             strcmp(grp_str, src_or_group))
    2019           0 :                                 continue;
    2020             :                 }
    2021           0 :                 pim_show_mlag_up_entry_detail(vrf, vty, up,
    2022             :                                               src_str, grp_str, json);
    2023             :         }
    2024             : 
    2025           0 :         if (uj)
    2026           0 :                 vty_json(vty, json);
    2027           0 : }
    2028             : 
    2029           0 : static void pim_show_mlag_up_vrf(struct vrf *vrf, struct vty *vty, bool uj)
    2030             : {
    2031           0 :         json_object *json = NULL;
    2032           0 :         json_object *json_row;
    2033           0 :         struct pim_upstream *up;
    2034           0 :         struct pim_instance *pim = vrf->info;
    2035           0 :         json_object *json_group = NULL;
    2036             : 
    2037           0 :         if (uj) {
    2038           0 :                 json = json_object_new_object();
    2039             :         } else {
    2040           0 :                 vty_out(vty,
    2041             :                         "Source          Group           Owner  Local-cost  Peer-cost  DF\n");
    2042             :         }
    2043             : 
    2044           0 :         frr_each (rb_pim_upstream, &pim->upstream_head, up) {
    2045           0 :                 if (!(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)
    2046           0 :                     && !(up->flags & PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE)
    2047           0 :                     && !pim_up_mlag_is_local(up))
    2048           0 :                         continue;
    2049           0 :                 if (uj) {
    2050           0 :                         char src_str[PIM_ADDRSTRLEN];
    2051           0 :                         char grp_str[PIM_ADDRSTRLEN];
    2052           0 :                         json_object *own_list = NULL;
    2053             : 
    2054           0 :                         snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
    2055             :                                    &up->sg.grp);
    2056           0 :                         snprintfrr(src_str, sizeof(src_str), "%pPAs",
    2057             :                                    &up->sg.src);
    2058             : 
    2059           0 :                         json_object_object_get_ex(json, grp_str, &json_group);
    2060           0 :                         if (!json_group) {
    2061           0 :                                 json_group = json_object_new_object();
    2062           0 :                                 json_object_object_add(json, grp_str,
    2063             :                                                        json_group);
    2064             :                         }
    2065             : 
    2066           0 :                         json_row = json_object_new_object();
    2067           0 :                         json_object_string_add(json_row, "vrf", vrf->name);
    2068           0 :                         json_object_string_add(json_row, "source", src_str);
    2069           0 :                         json_object_string_add(json_row, "group", grp_str);
    2070             : 
    2071           0 :                         own_list = json_object_new_array();
    2072           0 :                         if (pim_up_mlag_is_local(up)) {
    2073             : 
    2074           0 :                                 json_object_array_add(own_list,
    2075             :                                                       json_object_new_string(
    2076             :                                                               "local"));
    2077             :                         }
    2078           0 :                         if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER)) {
    2079           0 :                                 json_object_array_add(own_list,
    2080             :                                                       json_object_new_string(
    2081             :                                                               "peer"));
    2082             :                         }
    2083           0 :                         json_object_object_add(json_row, "owners", own_list);
    2084             : 
    2085           0 :                         json_object_int_add(json_row, "localCost",
    2086           0 :                                             pim_up_mlag_local_cost(up));
    2087           0 :                         json_object_int_add(json_row, "peerCost",
    2088           0 :                                             pim_up_mlag_peer_cost(up));
    2089           0 :                         if (PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags))
    2090           0 :                                 json_object_boolean_false_add(json_row, "df");
    2091             :                         else
    2092           0 :                                 json_object_boolean_true_add(json_row, "df");
    2093           0 :                         json_object_object_add(json_group, src_str, json_row);
    2094             :                 } else {
    2095           0 :                         char own_str[6];
    2096             : 
    2097           0 :                         own_str[0] = '\0';
    2098           0 :                         if (pim_up_mlag_is_local(up))
    2099           0 :                                 strlcat(own_str, "L", sizeof(own_str));
    2100           0 :                         if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_PEER))
    2101           0 :                                 strlcat(own_str, "P", sizeof(own_str));
    2102           0 :                         if (up->flags & (PIM_UPSTREAM_FLAG_MASK_MLAG_INTERFACE))
    2103           0 :                                 strlcat(own_str, "I", sizeof(own_str));
    2104           0 :                         vty_out(vty,
    2105             :                                 "%-15pPAs %-15pPAs %-6s %-11u %-10u %2s\n",
    2106             :                                 &up->sg.src, &up->sg.grp, own_str,
    2107             :                                 pim_up_mlag_local_cost(up),
    2108             :                                 pim_up_mlag_peer_cost(up),
    2109           0 :                                 PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)
    2110             :                                 ? "n" : "y");
    2111             :                 }
    2112             :         }
    2113           0 :         if (uj)
    2114           0 :                 vty_json(vty, json);
    2115           0 : }
    2116             : 
    2117           0 : static void pim_show_mlag_help_string(struct vty *vty, bool uj)
    2118             : {
    2119           0 :         if (!uj) {
    2120           0 :                 vty_out(vty, "Owner codes:\n");
    2121           0 :                 vty_out(vty,
    2122             :                         "L: EVPN-MLAG Entry, I:PIM-MLAG Entry, P: Peer Entry\n");
    2123             :         }
    2124           0 : }
    2125             : 
    2126             : 
    2127           0 : DEFUN(show_ip_pim_mlag_up, show_ip_pim_mlag_up_cmd,
    2128             :       "show ip pim [vrf NAME] mlag upstream [A.B.C.D [A.B.C.D]] [json]",
    2129             :       SHOW_STR
    2130             :       IP_STR
    2131             :       PIM_STR
    2132             :       VRF_CMD_HELP_STR
    2133             :       "MLAG\n"
    2134             :       "upstream\n"
    2135             :       "Unicast or Multicast address\n"
    2136             :       "Multicast address\n" JSON_STR)
    2137             : {
    2138           0 :         const char *src_or_group = NULL;
    2139           0 :         const char *group = NULL;
    2140           0 :         int idx = 2;
    2141           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    2142           0 :         bool uj = use_json(argc, argv);
    2143             : 
    2144           0 :         if (!vrf || !vrf->info) {
    2145           0 :                 vty_out(vty, "%s: VRF or Info missing\n", __func__);
    2146           0 :                 return CMD_WARNING;
    2147             :         }
    2148             : 
    2149           0 :         if (uj)
    2150           0 :                 argc--;
    2151             : 
    2152           0 :         if (argv_find(argv, argc, "A.B.C.D", &idx)) {
    2153           0 :                 src_or_group = argv[idx]->arg;
    2154           0 :                 if (idx + 1 < argc)
    2155           0 :                         group = argv[idx + 1]->arg;
    2156             :         }
    2157             : 
    2158           0 :         pim_show_mlag_help_string(vty, uj);
    2159             : 
    2160           0 :         if (src_or_group)
    2161           0 :                 pim_show_mlag_up_detail(vrf, vty, src_or_group, group, uj);
    2162             :         else
    2163           0 :                 pim_show_mlag_up_vrf(vrf, vty, uj);
    2164             : 
    2165             :         return CMD_SUCCESS;
    2166             : }
    2167             : 
    2168             : 
    2169           0 : DEFUN(show_ip_pim_mlag_up_vrf_all, show_ip_pim_mlag_up_vrf_all_cmd,
    2170             :       "show ip pim vrf all mlag upstream [json]",
    2171             :       SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR
    2172             :       "MLAG\n"
    2173             :       "upstream\n" JSON_STR)
    2174             : {
    2175           0 :         struct vrf *vrf;
    2176           0 :         bool uj = use_json(argc, argv);
    2177             : 
    2178           0 :         pim_show_mlag_help_string(vty, uj);
    2179           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    2180           0 :                 pim_show_mlag_up_vrf(vrf, vty, uj);
    2181             :         }
    2182             : 
    2183           0 :         return CMD_SUCCESS;
    2184             : }
    2185             : 
    2186           0 : DEFPY (show_ip_pim_neighbor,
    2187             :        show_ip_pim_neighbor_cmd,
    2188             :        "show ip pim [vrf NAME] neighbor [detail|WORD]$interface [json$json]",
    2189             :        SHOW_STR
    2190             :        IP_STR
    2191             :        PIM_STR
    2192             :        VRF_CMD_HELP_STR
    2193             :        "PIM neighbor information\n"
    2194             :        "Detailed output\n"
    2195             :        "Name of interface or neighbor\n"
    2196             :        JSON_STR)
    2197             : {
    2198           0 :         return pim_show_neighbors_cmd_helper(vrf, vty, json, interface);
    2199             : }
    2200             : 
    2201           0 : DEFPY (show_ip_pim_neighbor_vrf_all,
    2202             :        show_ip_pim_neighbor_vrf_all_cmd,
    2203             :        "show ip pim vrf all neighbor [detail|WORD]$interface [json$json]",
    2204             :        SHOW_STR
    2205             :        IP_STR
    2206             :        PIM_STR
    2207             :        VRF_CMD_HELP_STR
    2208             :        "PIM neighbor information\n"
    2209             :        "Detailed output\n"
    2210             :        "Name of interface or neighbor\n"
    2211             :        JSON_STR)
    2212             : {
    2213           0 :         return pim_show_neighbors_vrf_all_cmd_helper(vty, json, interface);
    2214             : }
    2215             : 
    2216           0 : DEFPY (show_ip_pim_secondary,
    2217             :        show_ip_pim_secondary_cmd,
    2218             :        "show ip pim [vrf NAME] secondary",
    2219             :        SHOW_STR
    2220             :        IP_STR
    2221             :        PIM_STR
    2222             :        VRF_CMD_HELP_STR
    2223             :        "PIM neighbor addresses\n")
    2224             : {
    2225           0 :         return pim_show_secondary_helper(vrf, vty);
    2226             : }
    2227             : 
    2228           0 : DEFPY (show_ip_pim_state,
    2229             :        show_ip_pim_state_cmd,
    2230             :        "show ip pim [vrf NAME] state [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
    2231             :        SHOW_STR
    2232             :        IP_STR
    2233             :        PIM_STR
    2234             :        VRF_CMD_HELP_STR
    2235             :        "PIM state information\n"
    2236             :        "Unicast or Multicast address\n"
    2237             :        "Multicast address\n"
    2238             :        JSON_STR)
    2239             : {
    2240           0 :         return pim_show_state_helper(vrf, vty, s_or_g_str, g_str, !!json);
    2241             : }
    2242             : 
    2243           0 : DEFPY (show_ip_pim_state_vrf_all,
    2244             :        show_ip_pim_state_vrf_all_cmd,
    2245             :        "show ip pim vrf all state [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
    2246             :        SHOW_STR
    2247             :        IP_STR
    2248             :        PIM_STR
    2249             :        VRF_CMD_HELP_STR
    2250             :        "PIM state information\n"
    2251             :        "Unicast or Multicast address\n"
    2252             :        "Multicast address\n"
    2253             :        JSON_STR)
    2254             : {
    2255           0 :         return pim_show_state_vrf_all_helper(vty, s_or_g_str, g_str, !!json);
    2256             : }
    2257             : 
    2258           0 : DEFPY (show_ip_pim_upstream,
    2259             :        show_ip_pim_upstream_cmd,
    2260             :        "show ip pim [vrf NAME] upstream [A.B.C.D$s_or_g [A.B.C.D$g]] [json$json]",
    2261             :        SHOW_STR
    2262             :        IP_STR
    2263             :        PIM_STR
    2264             :        VRF_CMD_HELP_STR
    2265             :        "PIM upstream information\n"
    2266             :        "The Source or Group\n"
    2267             :        "The Group\n"
    2268             :        JSON_STR)
    2269             : {
    2270           0 :         return pim_show_upstream_helper(vrf, vty, s_or_g, g, !!json);
    2271             : }
    2272             : 
    2273           0 : DEFPY (show_ip_pim_upstream_vrf_all,
    2274             :        show_ip_pim_upstream_vrf_all_cmd,
    2275             :        "show ip pim vrf all upstream [json$json]",
    2276             :        SHOW_STR
    2277             :        IP_STR
    2278             :        PIM_STR
    2279             :        VRF_CMD_HELP_STR
    2280             :        "PIM upstream information\n"
    2281             :        JSON_STR)
    2282             : {
    2283           0 :         return pim_show_upstream_vrf_all_helper(vty, !!json);
    2284             : }
    2285             : 
    2286           0 : DEFPY (show_ip_pim_channel,
    2287             :        show_ip_pim_channel_cmd,
    2288             :        "show ip pim [vrf NAME] channel [json$json]",
    2289             :        SHOW_STR
    2290             :        IP_STR
    2291             :        PIM_STR
    2292             :        VRF_CMD_HELP_STR
    2293             :        "PIM downstream channel info\n"
    2294             :        JSON_STR)
    2295             : {
    2296           0 :         return pim_show_channel_cmd_helper(vrf, vty, !!json);
    2297             : }
    2298             : 
    2299           0 : DEFPY (show_ip_pim_upstream_join_desired,
    2300             :        show_ip_pim_upstream_join_desired_cmd,
    2301             :        "show ip pim [vrf NAME] upstream-join-desired [json$json]",
    2302             :        SHOW_STR
    2303             :        IP_STR
    2304             :        PIM_STR
    2305             :        VRF_CMD_HELP_STR
    2306             :        "PIM upstream join-desired\n"
    2307             :        JSON_STR)
    2308             : {
    2309           0 :         return pim_show_upstream_join_desired_helper(vrf, vty, !!json);
    2310             : }
    2311             : 
    2312           0 : DEFPY (show_ip_pim_upstream_rpf,
    2313             :        show_ip_pim_upstream_rpf_cmd,
    2314             :        "show ip pim [vrf NAME] upstream-rpf [json$json]",
    2315             :        SHOW_STR
    2316             :        IP_STR
    2317             :        PIM_STR
    2318             :        VRF_CMD_HELP_STR
    2319             :        "PIM upstream source rpf\n"
    2320             :        JSON_STR)
    2321             : {
    2322           0 :         return pim_show_upstream_rpf_helper(vrf, vty, !!json);
    2323             : }
    2324             : 
    2325           0 : DEFPY (show_ip_pim_rp,
    2326             :        show_ip_pim_rp_cmd,
    2327             :        "show ip pim [vrf NAME] rp-info [A.B.C.D/M$group] [json$json]",
    2328             :        SHOW_STR
    2329             :        IP_STR
    2330             :        PIM_STR
    2331             :        VRF_CMD_HELP_STR
    2332             :        "PIM RP information\n"
    2333             :        "Multicast Group range\n"
    2334             :        JSON_STR)
    2335             : {
    2336           0 :         return pim_show_rp_helper(vrf, vty, group_str, (struct prefix *)group,
    2337             :                                   !!json);
    2338             : }
    2339             : 
    2340           0 : DEFPY (show_ip_pim_rp_vrf_all,
    2341             :        show_ip_pim_rp_vrf_all_cmd,
    2342             :        "show ip pim vrf all rp-info [A.B.C.D/M$group] [json$json]",
    2343             :        SHOW_STR
    2344             :        IP_STR
    2345             :        PIM_STR
    2346             :        VRF_CMD_HELP_STR
    2347             :        "PIM RP information\n"
    2348             :        "Multicast Group range\n"
    2349             :        JSON_STR)
    2350             : {
    2351           0 :         return pim_show_rp_vrf_all_helper(vty, group_str,
    2352             :                                           (struct prefix *)group, !!json);
    2353             : }
    2354             : 
    2355           0 : DEFPY (show_ip_pim_rpf,
    2356             :        show_ip_pim_rpf_cmd,
    2357             :        "show ip pim [vrf NAME] rpf [json$json]",
    2358             :        SHOW_STR
    2359             :        IP_STR
    2360             :        PIM_STR
    2361             :        VRF_CMD_HELP_STR
    2362             :        "PIM cached source rpf information\n"
    2363             :        JSON_STR)
    2364             : {
    2365           0 :         return pim_show_rpf_helper(vrf, vty, !!json);
    2366             : }
    2367             : 
    2368           0 : DEFPY (show_ip_pim_rpf_vrf_all,
    2369             :        show_ip_pim_rpf_vrf_all_cmd,
    2370             :        "show ip pim vrf all rpf [json$json]",
    2371             :        SHOW_STR
    2372             :        IP_STR
    2373             :        PIM_STR
    2374             :        VRF_CMD_HELP_STR
    2375             :        "PIM cached source rpf information\n"
    2376             :        JSON_STR)
    2377             : {
    2378           0 :         return pim_show_rpf_vrf_all_helper(vty, !!json);
    2379             : }
    2380             : 
    2381           0 : DEFPY (show_ip_pim_nexthop,
    2382             :        show_ip_pim_nexthop_cmd,
    2383             :        "show ip pim [vrf NAME] nexthop [json$json]",
    2384             :        SHOW_STR
    2385             :        IP_STR
    2386             :        PIM_STR
    2387             :        VRF_CMD_HELP_STR
    2388             :        "PIM cached nexthop rpf information\n"
    2389             :        JSON_STR)
    2390             : {
    2391           0 :         return pim_show_nexthop_cmd_helper(vrf, vty, !!json);
    2392             : }
    2393             : 
    2394           0 : DEFPY (show_ip_pim_nexthop_lookup,
    2395             :        show_ip_pim_nexthop_lookup_cmd,
    2396             :        "show ip pim [vrf NAME] nexthop-lookup A.B.C.D$source A.B.C.D$group",
    2397             :        SHOW_STR
    2398             :        IP_STR
    2399             :        PIM_STR
    2400             :        VRF_CMD_HELP_STR
    2401             :        "PIM cached nexthop rpf lookup\n"
    2402             :        "Source/RP address\n"
    2403             :        "Multicast Group address\n")
    2404             : {
    2405           0 :         return pim_show_nexthop_lookup_cmd_helper(vrf, vty, source, group);
    2406             : }
    2407             : 
    2408           0 : DEFPY (show_ip_pim_interface_traffic,
    2409             :        show_ip_pim_interface_traffic_cmd,
    2410             :        "show ip pim [vrf NAME] interface traffic [WORD$if_name] [json$json]",
    2411             :        SHOW_STR
    2412             :        IP_STR
    2413             :        PIM_STR
    2414             :        VRF_CMD_HELP_STR
    2415             :        "PIM interface information\n"
    2416             :        "Protocol Packet counters\n"
    2417             :        "Interface name\n"
    2418             :        JSON_STR)
    2419             : {
    2420           0 :         return pim_show_interface_traffic_helper(vrf, if_name, vty, !!json);
    2421             : }
    2422             : 
    2423           0 : DEFPY (show_ip_pim_bsm_db,
    2424             :        show_ip_pim_bsm_db_cmd,
    2425             :        "show ip pim bsm-database [vrf NAME] [json$json]",
    2426             :        SHOW_STR
    2427             :        IP_STR
    2428             :        PIM_STR
    2429             :        "PIM cached bsm packets information\n"
    2430             :        VRF_CMD_HELP_STR
    2431             :        JSON_STR)
    2432             : {
    2433           0 :         return pim_show_bsm_db_helper(vrf, vty, !!json);
    2434             : }
    2435             : 
    2436           0 : DEFPY (show_ip_pim_bsrp,
    2437             :        show_ip_pim_bsrp_cmd,
    2438             :        "show ip pim bsrp-info [vrf NAME] [json$json]",
    2439             :        SHOW_STR
    2440             :        IP_STR
    2441             :        PIM_STR
    2442             :        "PIM cached group-rp mappings information\n"
    2443             :        VRF_CMD_HELP_STR
    2444             :        JSON_STR)
    2445             : {
    2446           0 :         return pim_show_group_rp_mappings_info_helper(vrf, vty, !!json);
    2447             : }
    2448             : 
    2449           0 : DEFPY (show_ip_pim_statistics,
    2450             :        show_ip_pim_statistics_cmd,
    2451             :        "show ip pim [vrf NAME] statistics [interface WORD$word] [json$json]",
    2452             :        SHOW_STR
    2453             :        IP_STR
    2454             :        PIM_STR
    2455             :        VRF_CMD_HELP_STR
    2456             :        "PIM statistics\n"
    2457             :        INTERFACE_STR
    2458             :        "PIM interface\n"
    2459             :        JSON_STR)
    2460             : {
    2461           0 :         return pim_show_statistics_helper(vrf, vty, word, !!json);
    2462             : }
    2463             : 
    2464           0 : DEFPY (show_ip_multicast,
    2465             :        show_ip_multicast_cmd,
    2466             :        "show ip multicast [vrf NAME]",
    2467             :        SHOW_STR
    2468             :        IP_STR
    2469             :        "Multicast global information\n"
    2470             :        VRF_CMD_HELP_STR)
    2471             : {
    2472           0 :         return pim_show_multicast_helper(vrf, vty);
    2473             : }
    2474             : 
    2475           0 : DEFPY (show_ip_multicast_vrf_all,
    2476             :        show_ip_multicast_vrf_all_cmd,
    2477             :        "show ip multicast vrf all",
    2478             :        SHOW_STR
    2479             :        IP_STR
    2480             :        "Multicast global information\n"
    2481             :        VRF_CMD_HELP_STR)
    2482             : {
    2483           0 :         return pim_show_multicast_vrf_all_helper(vty);
    2484             : }
    2485             : 
    2486           0 : DEFPY (show_ip_multicast_count,
    2487             :        show_ip_multicast_count_cmd,
    2488             :        "show ip multicast count [vrf NAME] [json$json]",
    2489             :        SHOW_STR
    2490             :        IP_STR
    2491             :        "Multicast global information\n"
    2492             :        "Data packet count\n"
    2493             :        VRF_CMD_HELP_STR
    2494             :        JSON_STR)
    2495             : {
    2496           0 :         return pim_show_multicast_count_helper(vrf, vty, !!json);
    2497             : }
    2498             : 
    2499           0 : DEFPY (show_ip_multicast_count_vrf_all,
    2500             :        show_ip_multicast_count_vrf_all_cmd,
    2501             :        "show ip multicast count vrf all [json$json]",
    2502             :        SHOW_STR
    2503             :        IP_STR
    2504             :        "Multicast global information\n"
    2505             :        "Data packet count\n"
    2506             :        VRF_CMD_HELP_STR
    2507             :        JSON_STR)
    2508             : {
    2509           0 :         return pim_show_multicast_count_vrf_all_helper(vty, !!json);
    2510             : }
    2511             : 
    2512           0 : DEFPY (show_ip_mroute,
    2513             :        show_ip_mroute_cmd,
    2514             :        "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]",
    2515             :        SHOW_STR
    2516             :        IP_STR
    2517             :        MROUTE_STR
    2518             :        VRF_CMD_HELP_STR
    2519             :        "The Source or Group\n"
    2520             :        "The Group\n"
    2521             :        "Fill in Assumed data\n"
    2522             :        JSON_STR)
    2523             : {
    2524           0 :         return pim_show_mroute_helper(vrf, vty, s_or_g, g, !!fill, !!json);
    2525             : }
    2526             : 
    2527           0 : DEFPY (show_ip_mroute_vrf_all,
    2528             :        show_ip_mroute_vrf_all_cmd,
    2529             :        "show ip mroute vrf all [fill$fill] [json$json]",
    2530             :        SHOW_STR
    2531             :        IP_STR
    2532             :        MROUTE_STR
    2533             :        VRF_CMD_HELP_STR
    2534             :        "Fill in Assumed data\n"
    2535             :        JSON_STR)
    2536             : {
    2537           0 :         return pim_show_mroute_vrf_all_helper(vty, !!fill, !!json);
    2538             : }
    2539             : 
    2540           0 : DEFPY (clear_ip_mroute_count,
    2541             :        clear_ip_mroute_count_cmd,
    2542             :        "clear ip mroute [vrf NAME]$name count",
    2543             :        CLEAR_STR
    2544             :        IP_STR
    2545             :        MROUTE_STR
    2546             :        VRF_CMD_HELP_STR
    2547             :        "Route and packet count data\n")
    2548             : {
    2549           0 :         return clear_ip_mroute_count_command(vty, name);
    2550             : }
    2551             : 
    2552           0 : DEFPY (show_ip_mroute_count,
    2553             :        show_ip_mroute_count_cmd,
    2554             :        "show ip mroute [vrf NAME] count [json$json]",
    2555             :        SHOW_STR
    2556             :        IP_STR
    2557             :        MROUTE_STR
    2558             :        VRF_CMD_HELP_STR
    2559             :        "Route and packet count data\n"
    2560             :        JSON_STR)
    2561             : {
    2562           0 :         return pim_show_mroute_count_helper(vrf, vty, !!json);
    2563             : }
    2564             : 
    2565           0 : DEFPY (show_ip_mroute_count_vrf_all,
    2566             :        show_ip_mroute_count_vrf_all_cmd,
    2567             :        "show ip mroute vrf all count [json$json]",
    2568             :        SHOW_STR
    2569             :        IP_STR
    2570             :        MROUTE_STR
    2571             :        VRF_CMD_HELP_STR
    2572             :        "Route and packet count data\n"
    2573             :        JSON_STR)
    2574             : {
    2575           0 :         return pim_show_mroute_count_vrf_all_helper(vty, !!json);
    2576             : }
    2577             : 
    2578           0 : DEFPY (show_ip_mroute_summary,
    2579             :        show_ip_mroute_summary_cmd,
    2580             :        "show ip mroute [vrf NAME] summary [json$json]",
    2581             :        SHOW_STR
    2582             :        IP_STR
    2583             :        MROUTE_STR
    2584             :        VRF_CMD_HELP_STR
    2585             :        "Summary of all mroutes\n"
    2586             :        JSON_STR)
    2587             : {
    2588           0 :         return pim_show_mroute_summary_helper(vrf, vty, !!json);
    2589             : }
    2590             : 
    2591           0 : DEFPY (show_ip_mroute_summary_vrf_all,
    2592             :        show_ip_mroute_summary_vrf_all_cmd,
    2593             :        "show ip mroute vrf all summary [json$json]",
    2594             :        SHOW_STR
    2595             :        IP_STR
    2596             :        MROUTE_STR
    2597             :        VRF_CMD_HELP_STR
    2598             :        "Summary of all mroutes\n"
    2599             :        JSON_STR)
    2600             : {
    2601           0 :         return pim_show_mroute_summary_vrf_all_helper(vty, !!json);
    2602             : }
    2603             : 
    2604           0 : DEFUN (show_ip_rib,
    2605             :        show_ip_rib_cmd,
    2606             :        "show ip rib [vrf NAME] A.B.C.D",
    2607             :        SHOW_STR
    2608             :        IP_STR
    2609             :        RIB_STR
    2610             :        VRF_CMD_HELP_STR
    2611             :        "Unicast address\n")
    2612             : {
    2613           0 :         int idx = 2;
    2614           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    2615           0 :         struct in_addr addr;
    2616           0 :         const char *addr_str;
    2617           0 :         struct pim_nexthop nexthop;
    2618           0 :         int result;
    2619             : 
    2620           0 :         if (!vrf)
    2621             :                 return CMD_WARNING;
    2622             : 
    2623           0 :         memset(&nexthop, 0, sizeof(nexthop));
    2624           0 :         argv_find(argv, argc, "A.B.C.D", &idx);
    2625           0 :         addr_str = argv[idx]->arg;
    2626           0 :         result = inet_pton(AF_INET, addr_str, &addr);
    2627           0 :         if (result <= 0) {
    2628           0 :                 vty_out(vty, "Bad unicast address %s: errno=%d: %s\n", addr_str,
    2629           0 :                         errno, safe_strerror(errno));
    2630           0 :                 return CMD_WARNING;
    2631             :         }
    2632             : 
    2633           0 :         if (!pim_nexthop_lookup(vrf->info, &nexthop, addr, 0)) {
    2634           0 :                 vty_out(vty,
    2635             :                         "Failure querying RIB nexthop for unicast address %s\n",
    2636             :                         addr_str);
    2637           0 :                 return CMD_WARNING;
    2638             :         }
    2639             : 
    2640           0 :         vty_out(vty,
    2641             :                 "Address         NextHop         Interface Metric Preference\n");
    2642             : 
    2643           0 :         vty_out(vty, "%-15s %-15pPAs %-9s %6d %10d\n", addr_str,
    2644             :                 &nexthop.mrib_nexthop_addr,
    2645           0 :                 nexthop.interface ? nexthop.interface->name : "<ifname?>",
    2646             :                 nexthop.mrib_route_metric, nexthop.mrib_metric_preference);
    2647             : 
    2648           0 :         return CMD_SUCCESS;
    2649             : }
    2650             : 
    2651           0 : static void show_ssmpingd(struct pim_instance *pim, struct vty *vty)
    2652             : {
    2653           0 :         struct listnode *node;
    2654           0 :         struct ssmpingd_sock *ss;
    2655           0 :         time_t now;
    2656             : 
    2657           0 :         vty_out(vty,
    2658             :                 "Source          Socket Address          Port Uptime   Requests\n");
    2659             : 
    2660           0 :         if (!pim->ssmpingd_list)
    2661             :                 return;
    2662             : 
    2663           0 :         now = pim_time_monotonic_sec();
    2664             : 
    2665           0 :         for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) {
    2666           0 :                 char source_str[INET_ADDRSTRLEN];
    2667           0 :                 char ss_uptime[10];
    2668           0 :                 struct sockaddr_in bind_addr;
    2669           0 :                 socklen_t len = sizeof(bind_addr);
    2670           0 :                 char bind_addr_str[INET_ADDRSTRLEN];
    2671             : 
    2672           0 :                 pim_inet4_dump("<src?>", ss->source_addr, source_str,
    2673             :                                sizeof(source_str));
    2674             : 
    2675           0 :                 if (pim_socket_getsockname(
    2676             :                             ss->sock_fd, (struct sockaddr *)&bind_addr, &len)) {
    2677           0 :                         vty_out(vty,
    2678             :                                 "%% Failure reading socket name for ssmpingd source %s on fd=%d\n",
    2679             :                                 source_str, ss->sock_fd);
    2680             :                 }
    2681             : 
    2682           0 :                 pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str,
    2683             :                                sizeof(bind_addr_str));
    2684           0 :                 pim_time_uptime(ss_uptime, sizeof(ss_uptime),
    2685           0 :                                 now - ss->creation);
    2686             : 
    2687           0 :                 vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld\n", source_str,
    2688           0 :                         ss->sock_fd, bind_addr_str, ntohs(bind_addr.sin_port),
    2689           0 :                         ss_uptime, (long long)ss->requests);
    2690             :         }
    2691             : }
    2692             : 
    2693           0 : DEFUN (show_ip_ssmpingd,
    2694             :        show_ip_ssmpingd_cmd,
    2695             :        "show ip ssmpingd [vrf NAME]",
    2696             :        SHOW_STR
    2697             :        IP_STR
    2698             :        SHOW_SSMPINGD_STR
    2699             :        VRF_CMD_HELP_STR)
    2700             : {
    2701           0 :         int idx = 2;
    2702           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    2703             : 
    2704           0 :         if (!vrf)
    2705             :                 return CMD_WARNING;
    2706             : 
    2707           0 :         show_ssmpingd(vrf->info, vty);
    2708           0 :         return CMD_SUCCESS;
    2709             : }
    2710             : 
    2711           0 : DEFUN (ip_pim_spt_switchover_infinity,
    2712             :        ip_pim_spt_switchover_infinity_cmd,
    2713             :        "ip pim spt-switchover infinity-and-beyond",
    2714             :        IP_STR
    2715             :        PIM_STR
    2716             :        "SPT-Switchover\n"
    2717             :        "Never switch to SPT Tree\n")
    2718             : {
    2719           0 :         return pim_process_spt_switchover_infinity_cmd(vty);
    2720             : }
    2721             : 
    2722           0 : DEFPY (ip_pim_spt_switchover_infinity_plist,
    2723             :        ip_pim_spt_switchover_infinity_plist_cmd,
    2724             :        "ip pim spt-switchover infinity-and-beyond prefix-list WORD$plist",
    2725             :        IP_STR
    2726             :        PIM_STR
    2727             :        "SPT-Switchover\n"
    2728             :        "Never switch to SPT Tree\n"
    2729             :        "Prefix-List to control which groups to switch\n"
    2730             :        "Prefix-List name\n")
    2731             : {
    2732           0 :         return pim_process_spt_switchover_prefixlist_cmd(vty, plist);
    2733             : }
    2734             : 
    2735           0 : DEFUN (no_ip_pim_spt_switchover_infinity,
    2736             :        no_ip_pim_spt_switchover_infinity_cmd,
    2737             :        "no ip pim spt-switchover infinity-and-beyond",
    2738             :        NO_STR
    2739             :        IP_STR
    2740             :        PIM_STR
    2741             :        "SPT_Switchover\n"
    2742             :        "Never switch to SPT Tree\n")
    2743             : {
    2744           0 :         return pim_process_no_spt_switchover_cmd(vty);
    2745             : }
    2746             : 
    2747           0 : DEFUN (no_ip_pim_spt_switchover_infinity_plist,
    2748             :        no_ip_pim_spt_switchover_infinity_plist_cmd,
    2749             :        "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
    2750             :        NO_STR
    2751             :        IP_STR
    2752             :        PIM_STR
    2753             :        "SPT_Switchover\n"
    2754             :        "Never switch to SPT Tree\n"
    2755             :        "Prefix-List to control which groups to switch\n"
    2756             :        "Prefix-List name\n")
    2757             : {
    2758           0 :         return pim_process_no_spt_switchover_cmd(vty);
    2759             : }
    2760             : 
    2761           0 : DEFPY (pim_register_accept_list,
    2762             :        pim_register_accept_list_cmd,
    2763             :        "[no] ip pim register-accept-list WORD$word",
    2764             :        NO_STR
    2765             :        IP_STR
    2766             :        PIM_STR
    2767             :        "Only accept registers from a specific source prefix list\n"
    2768             :        "Prefix-List name\n")
    2769             : {
    2770           0 :         const char *vrfname;
    2771           0 :         char reg_alist_xpath[XPATH_MAXLEN];
    2772             : 
    2773           0 :         vrfname = pim_cli_get_vrf_name(vty);
    2774           0 :         if (vrfname == NULL)
    2775             :                 return CMD_WARNING_CONFIG_FAILED;
    2776             : 
    2777           0 :         snprintf(reg_alist_xpath, sizeof(reg_alist_xpath),
    2778             :                  FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
    2779             :                  "frr-routing:ipv4");
    2780           0 :         strlcat(reg_alist_xpath, "/register-accept-list",
    2781             :                 sizeof(reg_alist_xpath));
    2782             : 
    2783           0 :         if (no)
    2784           0 :                 nb_cli_enqueue_change(vty, reg_alist_xpath,
    2785             :                                       NB_OP_DESTROY, NULL);
    2786             :         else
    2787           0 :                 nb_cli_enqueue_change(vty, reg_alist_xpath,
    2788             :                                       NB_OP_MODIFY, word);
    2789             : 
    2790           0 :         return nb_cli_apply_changes(vty, NULL);
    2791             : }
    2792             : 
    2793           0 : DEFPY (ip_pim_joinprune_time,
    2794             :        ip_pim_joinprune_time_cmd,
    2795             :        "ip pim join-prune-interval (1-65535)$jpi",
    2796             :        IP_STR
    2797             :        "pim multicast routing\n"
    2798             :        "Join Prune Send Interval\n"
    2799             :        "Seconds\n")
    2800             : {
    2801           0 :         return pim_process_join_prune_cmd(vty, jpi_str);
    2802             : }
    2803             : 
    2804           0 : DEFUN (no_ip_pim_joinprune_time,
    2805             :        no_ip_pim_joinprune_time_cmd,
    2806             :        "no ip pim join-prune-interval [(1-65535)]",
    2807             :        NO_STR
    2808             :        IP_STR
    2809             :        "pim multicast routing\n"
    2810             :        "Join Prune Send Interval\n"
    2811             :        IGNORED_IN_NO_STR)
    2812             : {
    2813           0 :         return pim_process_no_join_prune_cmd(vty);
    2814             : }
    2815             : 
    2816           0 : DEFPY (ip_pim_register_suppress,
    2817             :        ip_pim_register_suppress_cmd,
    2818             :        "ip pim register-suppress-time (1-65535)$rst",
    2819             :        IP_STR
    2820             :        "pim multicast routing\n"
    2821             :        "Register Suppress Timer\n"
    2822             :        "Seconds\n")
    2823             : {
    2824           0 :         return pim_process_register_suppress_cmd(vty, rst_str);
    2825             : }
    2826             : 
    2827           0 : DEFUN (no_ip_pim_register_suppress,
    2828             :        no_ip_pim_register_suppress_cmd,
    2829             :        "no ip pim register-suppress-time [(1-65535)]",
    2830             :        NO_STR
    2831             :        IP_STR
    2832             :        "pim multicast routing\n"
    2833             :        "Register Suppress Timer\n"
    2834             :        IGNORED_IN_NO_STR)
    2835             : {
    2836           0 :         return pim_process_no_register_suppress_cmd(vty);
    2837             : }
    2838             : 
    2839           0 : DEFPY (ip_pim_rp_keep_alive,
    2840             :        ip_pim_rp_keep_alive_cmd,
    2841             :        "ip pim rp keep-alive-timer (1-65535)$kat",
    2842             :        IP_STR
    2843             :        "pim multicast routing\n"
    2844             :        "Rendezvous Point\n"
    2845             :        "Keep alive Timer\n"
    2846             :        "Seconds\n")
    2847             : {
    2848           0 :         return pim_process_rp_kat_cmd(vty, kat_str);
    2849             : }
    2850             : 
    2851           0 : DEFUN (no_ip_pim_rp_keep_alive,
    2852             :        no_ip_pim_rp_keep_alive_cmd,
    2853             :        "no ip pim rp keep-alive-timer [(1-65535)]",
    2854             :        NO_STR
    2855             :        IP_STR
    2856             :        "pim multicast routing\n"
    2857             :        "Rendezvous Point\n"
    2858             :        "Keep alive Timer\n"
    2859             :        IGNORED_IN_NO_STR)
    2860             : {
    2861           0 :         return pim_process_no_rp_kat_cmd(vty);
    2862             : }
    2863             : 
    2864           0 : DEFPY (ip_pim_keep_alive,
    2865             :        ip_pim_keep_alive_cmd,
    2866             :        "ip pim keep-alive-timer (1-65535)$kat",
    2867             :        IP_STR
    2868             :        "pim multicast routing\n"
    2869             :        "Keep alive Timer\n"
    2870             :        "Seconds\n")
    2871             : {
    2872           0 :         return pim_process_keepalivetimer_cmd(vty, kat_str);
    2873             : }
    2874             : 
    2875           0 : DEFUN (no_ip_pim_keep_alive,
    2876             :        no_ip_pim_keep_alive_cmd,
    2877             :        "no ip pim keep-alive-timer [(1-65535)]",
    2878             :        NO_STR
    2879             :        IP_STR
    2880             :        "pim multicast routing\n"
    2881             :        "Keep alive Timer\n"
    2882             :        IGNORED_IN_NO_STR)
    2883             : {
    2884           0 :         return pim_process_no_keepalivetimer_cmd(vty);
    2885             : }
    2886             : 
    2887           0 : DEFPY (ip_pim_packets,
    2888             :        ip_pim_packets_cmd,
    2889             :        "ip pim packets (1-255)",
    2890             :        IP_STR
    2891             :        "pim multicast routing\n"
    2892             :        "packets to process at one time per fd\n"
    2893             :        "Number of packets\n")
    2894             : {
    2895           0 :         return pim_process_pim_packet_cmd(vty, packets_str);
    2896             : }
    2897             : 
    2898           0 : DEFUN (no_ip_pim_packets,
    2899             :        no_ip_pim_packets_cmd,
    2900             :        "no ip pim packets [(1-255)]",
    2901             :        NO_STR
    2902             :        IP_STR
    2903             :        "pim multicast routing\n"
    2904             :        "packets to process at one time per fd\n"
    2905             :        IGNORED_IN_NO_STR)
    2906             : {
    2907           0 :         return pim_process_no_pim_packet_cmd(vty);
    2908             : }
    2909             : 
    2910           0 : DEFPY (ip_igmp_group_watermark,
    2911             :        ip_igmp_group_watermark_cmd,
    2912             :        "ip igmp watermark-warn (1-65535)$limit",
    2913             :        IP_STR
    2914             :        IGMP_STR
    2915             :        "Configure group limit for watermark warning\n"
    2916             :        "Group count to generate watermark warning\n")
    2917             : {
    2918           0 :         PIM_DECLVAR_CONTEXT_VRF(vrf, pim);
    2919           0 :         pim->gm_watermark_limit = limit;
    2920             : 
    2921           0 :         return CMD_SUCCESS;
    2922             : }
    2923             : 
    2924           0 : DEFPY (no_ip_igmp_group_watermark,
    2925             :        no_ip_igmp_group_watermark_cmd,
    2926             :        "no ip igmp watermark-warn [(1-65535)$limit]",
    2927             :        NO_STR
    2928             :        IP_STR
    2929             :        IGMP_STR
    2930             :        "Unconfigure group limit for watermark warning\n"
    2931             :        IGNORED_IN_NO_STR)
    2932             : {
    2933           0 :         PIM_DECLVAR_CONTEXT_VRF(vrf, pim);
    2934           0 :         pim->gm_watermark_limit = 0;
    2935             : 
    2936           0 :         return CMD_SUCCESS;
    2937             : }
    2938             : 
    2939           0 : DEFUN (ip_pim_v6_secondary,
    2940             :        ip_pim_v6_secondary_cmd,
    2941             :        "ip pim send-v6-secondary",
    2942             :        IP_STR
    2943             :        "pim multicast routing\n"
    2944             :        "Send v6 secondary addresses\n")
    2945             : {
    2946           0 :         const char *vrfname;
    2947           0 :         char send_v6_secondary_xpath[XPATH_MAXLEN];
    2948             : 
    2949           0 :         vrfname = pim_cli_get_vrf_name(vty);
    2950           0 :         if (vrfname == NULL)
    2951             :                 return CMD_WARNING_CONFIG_FAILED;
    2952             : 
    2953           0 :         snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
    2954             :                  FRR_PIM_VRF_XPATH,
    2955             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    2956           0 :         strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
    2957             :                 sizeof(send_v6_secondary_xpath));
    2958             : 
    2959           0 :         nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
    2960             :                               "true");
    2961             : 
    2962           0 :         return nb_cli_apply_changes(vty, NULL);
    2963             : }
    2964             : 
    2965           0 : DEFUN (no_ip_pim_v6_secondary,
    2966             :        no_ip_pim_v6_secondary_cmd,
    2967             :        "no ip pim send-v6-secondary",
    2968             :        NO_STR
    2969             :        IP_STR
    2970             :        "pim multicast routing\n"
    2971             :        "Send v6 secondary addresses\n")
    2972             : {
    2973           0 :         const char *vrfname;
    2974           0 :         char send_v6_secondary_xpath[XPATH_MAXLEN];
    2975             : 
    2976           0 :         vrfname = pim_cli_get_vrf_name(vty);
    2977           0 :         if (vrfname == NULL)
    2978             :                 return CMD_WARNING_CONFIG_FAILED;
    2979             : 
    2980           0 :         snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
    2981             :                  FRR_PIM_VRF_XPATH,
    2982             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    2983           0 :         strlcat(send_v6_secondary_xpath, "/send-v6-secondary",
    2984             :                 sizeof(send_v6_secondary_xpath));
    2985             : 
    2986           0 :         nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY,
    2987             :                               "false");
    2988             : 
    2989           0 :         return nb_cli_apply_changes(vty, NULL);
    2990             : }
    2991             : 
    2992           0 : DEFPY (ip_pim_rp,
    2993             :        ip_pim_rp_cmd,
    2994             :        "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
    2995             :        IP_STR
    2996             :        "pim multicast routing\n"
    2997             :        "Rendezvous Point\n"
    2998             :        "ip address of RP\n"
    2999             :        "Group Address range to cover\n")
    3000             : {
    3001           0 :         const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
    3002             : 
    3003           0 :         return pim_process_rp_cmd(vty, rp_str, group_str);
    3004             : }
    3005             : 
    3006           0 : DEFPY (ip_pim_rp_prefix_list,
    3007             :        ip_pim_rp_prefix_list_cmd,
    3008             :        "ip pim rp A.B.C.D$rp prefix-list WORD$plist",
    3009             :        IP_STR
    3010             :        "pim multicast routing\n"
    3011             :        "Rendezvous Point\n"
    3012             :        "ip address of RP\n"
    3013             :        "group prefix-list filter\n"
    3014             :        "Name of a prefix-list\n")
    3015             : {
    3016           0 :         return pim_process_rp_plist_cmd(vty, rp_str, plist);
    3017             : }
    3018             : 
    3019           0 : DEFPY (no_ip_pim_rp,
    3020             :        no_ip_pim_rp_cmd,
    3021             :        "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp",
    3022             :        NO_STR
    3023             :        IP_STR
    3024             :        "pim multicast routing\n"
    3025             :        "Rendezvous Point\n"
    3026             :        "ip address of RP\n"
    3027             :        "Group Address range to cover\n")
    3028             : {
    3029           0 :         const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4";
    3030             : 
    3031           0 :         return pim_process_no_rp_cmd(vty, rp_str, group_str);
    3032             : }
    3033             : 
    3034           0 : DEFPY (no_ip_pim_rp_prefix_list,
    3035             :        no_ip_pim_rp_prefix_list_cmd,
    3036             :        "no ip pim rp A.B.C.D$rp prefix-list WORD$plist",
    3037             :        NO_STR
    3038             :        IP_STR
    3039             :        "pim multicast routing\n"
    3040             :        "Rendezvous Point\n"
    3041             :        "ip address of RP\n"
    3042             :        "group prefix-list filter\n"
    3043             :        "Name of a prefix-list\n")
    3044             : {
    3045           0 :         return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
    3046             : }
    3047             : 
    3048           0 : DEFUN (ip_pim_ssm_prefix_list,
    3049             :        ip_pim_ssm_prefix_list_cmd,
    3050             :        "ip pim ssm prefix-list WORD",
    3051             :        IP_STR
    3052             :        "pim multicast routing\n"
    3053             :        "Source Specific Multicast\n"
    3054             :        "group range prefix-list filter\n"
    3055             :        "Name of a prefix-list\n")
    3056             : {
    3057           0 :         const char *vrfname;
    3058           0 :         char ssm_plist_xpath[XPATH_MAXLEN];
    3059             : 
    3060           0 :         vrfname = pim_cli_get_vrf_name(vty);
    3061           0 :         if (vrfname == NULL)
    3062             :                 return CMD_WARNING_CONFIG_FAILED;
    3063             : 
    3064           0 :         snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), FRR_PIM_VRF_XPATH,
    3065             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    3066           0 :         strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
    3067             : 
    3068           0 :         nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, argv[4]->arg);
    3069             : 
    3070           0 :         return nb_cli_apply_changes(vty, NULL);
    3071             : }
    3072             : 
    3073           0 : DEFUN (no_ip_pim_ssm_prefix_list,
    3074             :        no_ip_pim_ssm_prefix_list_cmd,
    3075             :        "no ip pim ssm prefix-list",
    3076             :        NO_STR
    3077             :        IP_STR
    3078             :        "pim multicast routing\n"
    3079             :        "Source Specific Multicast\n"
    3080             :        "group range prefix-list filter\n")
    3081             : {
    3082           0 :         const char *vrfname;
    3083           0 :         char ssm_plist_xpath[XPATH_MAXLEN];
    3084             : 
    3085           0 :         vrfname = pim_cli_get_vrf_name(vty);
    3086           0 :         if (vrfname == NULL)
    3087             :                 return CMD_WARNING_CONFIG_FAILED;
    3088             : 
    3089           0 :         snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
    3090             :                  FRR_PIM_VRF_XPATH,
    3091             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    3092           0 :         strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
    3093             : 
    3094           0 :         nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL);
    3095             : 
    3096           0 :         return nb_cli_apply_changes(vty, NULL);
    3097             : }
    3098             : 
    3099           0 : DEFUN (no_ip_pim_ssm_prefix_list_name,
    3100             :        no_ip_pim_ssm_prefix_list_name_cmd,
    3101             :        "no ip pim ssm prefix-list WORD",
    3102             :        NO_STR
    3103             :        IP_STR
    3104             :        "pim multicast routing\n"
    3105             :        "Source Specific Multicast\n"
    3106             :        "group range prefix-list filter\n"
    3107             :        "Name of a prefix-list\n")
    3108             : {
    3109           0 :         const char *vrfname;
    3110           0 :         const struct lyd_node *ssm_plist_dnode;
    3111           0 :         char ssm_plist_xpath[XPATH_MAXLEN];
    3112           0 :         const char *ssm_plist_name;
    3113             : 
    3114           0 :         vrfname = pim_cli_get_vrf_name(vty);
    3115           0 :         if (vrfname == NULL)
    3116             :                 return CMD_WARNING_CONFIG_FAILED;
    3117             : 
    3118           0 :         snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
    3119             :                  FRR_PIM_VRF_XPATH,
    3120             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    3121           0 :         strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
    3122           0 :         ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode,
    3123             :                                          ssm_plist_xpath);
    3124             : 
    3125           0 :         if (!ssm_plist_dnode) {
    3126           0 :                 vty_out(vty,
    3127             :                         "%% pim ssm prefix-list %s doesn't exist\n",
    3128           0 :                         argv[5]->arg);
    3129           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3130             :         }
    3131             : 
    3132           0 :         ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, ".");
    3133             : 
    3134           0 :         if (ssm_plist_name && !strcmp(ssm_plist_name, argv[5]->arg)) {
    3135           0 :                 nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY,
    3136             :                                       NULL);
    3137             : 
    3138           0 :                 return nb_cli_apply_changes(vty, NULL);
    3139             :         }
    3140             : 
    3141           0 :         vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
    3142             : 
    3143           0 :         return CMD_WARNING_CONFIG_FAILED;
    3144             : }
    3145             : 
    3146           0 : DEFUN (show_ip_pim_ssm_range,
    3147             :        show_ip_pim_ssm_range_cmd,
    3148             :        "show ip pim [vrf NAME] group-type [json]",
    3149             :        SHOW_STR
    3150             :        IP_STR
    3151             :        PIM_STR
    3152             :        VRF_CMD_HELP_STR
    3153             :        "PIM group type\n"
    3154             :        JSON_STR)
    3155             : {
    3156           0 :         int idx = 2;
    3157           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    3158           0 :         bool uj = use_json(argc, argv);
    3159             : 
    3160           0 :         if (!vrf)
    3161             :                 return CMD_WARNING;
    3162             : 
    3163           0 :         ip_pim_ssm_show_group_range(vrf->info, vty, uj);
    3164             : 
    3165           0 :         return CMD_SUCCESS;
    3166             : }
    3167             : 
    3168           0 : static void ip_pim_ssm_show_group_type(struct pim_instance *pim,
    3169             :                                        struct vty *vty, bool uj,
    3170             :                                        const char *group)
    3171             : {
    3172           0 :         struct in_addr group_addr;
    3173           0 :         const char *type_str;
    3174           0 :         int result;
    3175             : 
    3176           0 :         result = inet_pton(AF_INET, group, &group_addr);
    3177           0 :         if (result <= 0)
    3178             :                 type_str = "invalid";
    3179             :         else {
    3180           0 :                 if (pim_is_group_224_4(group_addr))
    3181           0 :                         type_str =
    3182           0 :                                 pim_is_grp_ssm(pim, group_addr) ? "SSM" : "ASM";
    3183             :                 else
    3184             :                         type_str = "not-multicast";
    3185             :         }
    3186             : 
    3187           0 :         if (uj) {
    3188           0 :                 json_object *json;
    3189           0 :                 json = json_object_new_object();
    3190           0 :                 json_object_string_add(json, "groupType", type_str);
    3191           0 :                 vty_json(vty, json);
    3192             :         } else
    3193           0 :                 vty_out(vty, "Group type : %s\n", type_str);
    3194           0 : }
    3195             : 
    3196           0 : DEFUN (show_ip_pim_group_type,
    3197             :        show_ip_pim_group_type_cmd,
    3198             :        "show ip pim [vrf NAME] group-type A.B.C.D [json]",
    3199             :        SHOW_STR
    3200             :        IP_STR
    3201             :        PIM_STR
    3202             :        VRF_CMD_HELP_STR
    3203             :        "multicast group type\n"
    3204             :        "group address\n"
    3205             :        JSON_STR)
    3206             : {
    3207           0 :         int idx = 2;
    3208           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    3209           0 :         bool uj = use_json(argc, argv);
    3210             : 
    3211           0 :         if (!vrf)
    3212             :                 return CMD_WARNING;
    3213             : 
    3214           0 :         argv_find(argv, argc, "A.B.C.D", &idx);
    3215           0 :         ip_pim_ssm_show_group_type(vrf->info, vty, uj, argv[idx]->arg);
    3216             : 
    3217           0 :         return CMD_SUCCESS;
    3218             : }
    3219             : 
    3220           5 : DEFPY (show_ip_pim_bsr,
    3221             :        show_ip_pim_bsr_cmd,
    3222             :        "show ip pim bsr [vrf NAME] [json$json]",
    3223             :        SHOW_STR
    3224             :        IP_STR
    3225             :        PIM_STR
    3226             :        "boot-strap router information\n"
    3227             :        VRF_CMD_HELP_STR
    3228             :        JSON_STR)
    3229             : {
    3230           5 :         return pim_show_bsr_helper(vrf, vty, !!json);
    3231             : }
    3232             : 
    3233           0 : DEFUN (ip_ssmpingd,
    3234             :        ip_ssmpingd_cmd,
    3235             :        "ip ssmpingd [A.B.C.D]",
    3236             :        IP_STR
    3237             :        CONF_SSMPINGD_STR
    3238             :        "Source address\n")
    3239             : {
    3240           0 :         int idx_ipv4 = 2;
    3241           0 :         const char *src_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
    3242             : 
    3243           0 :         return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str);
    3244             : }
    3245             : 
    3246           0 : DEFUN (no_ip_ssmpingd,
    3247             :        no_ip_ssmpingd_cmd,
    3248             :        "no ip ssmpingd [A.B.C.D]",
    3249             :        NO_STR
    3250             :        IP_STR
    3251             :        CONF_SSMPINGD_STR
    3252             :        "Source address\n")
    3253             : {
    3254           0 :         int idx_ipv4 = 3;
    3255           0 :         const char *src_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
    3256             : 
    3257           0 :         return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str);
    3258             : }
    3259             : 
    3260           0 : DEFUN (ip_pim_ecmp,
    3261             :        ip_pim_ecmp_cmd,
    3262             :        "ip pim ecmp",
    3263             :        IP_STR
    3264             :        "pim multicast routing\n"
    3265             :        "Enable PIM ECMP \n")
    3266             : {
    3267           0 :         const char *vrfname;
    3268           0 :         char ecmp_xpath[XPATH_MAXLEN];
    3269             : 
    3270           0 :         vrfname = pim_cli_get_vrf_name(vty);
    3271           0 :         if (vrfname == NULL)
    3272             :                 return CMD_WARNING_CONFIG_FAILED;
    3273             : 
    3274           0 :         snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
    3275             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    3276           0 :         strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
    3277             : 
    3278           0 :         nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
    3279           0 :         return nb_cli_apply_changes(vty, NULL);
    3280             : }
    3281             : 
    3282           0 : DEFUN (no_ip_pim_ecmp,
    3283             :        no_ip_pim_ecmp_cmd,
    3284             :        "no ip pim ecmp",
    3285             :        NO_STR
    3286             :        IP_STR
    3287             :        "pim multicast routing\n"
    3288             :        "Disable PIM ECMP \n")
    3289             : {
    3290           0 :         const char *vrfname;
    3291           0 :         char ecmp_xpath[XPATH_MAXLEN];
    3292             : 
    3293           0 :         vrfname = pim_cli_get_vrf_name(vty);
    3294           0 :         if (vrfname == NULL)
    3295             :                 return CMD_WARNING_CONFIG_FAILED;
    3296             : 
    3297           0 :         snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
    3298             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    3299           0 :         strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
    3300             : 
    3301           0 :         nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "false");
    3302             : 
    3303           0 :         return nb_cli_apply_changes(vty, NULL);
    3304             : }
    3305             : 
    3306           0 : DEFUN (ip_pim_ecmp_rebalance,
    3307             :        ip_pim_ecmp_rebalance_cmd,
    3308             :        "ip pim ecmp rebalance",
    3309             :        IP_STR
    3310             :        "pim multicast routing\n"
    3311             :        "Enable PIM ECMP \n"
    3312             :        "Enable PIM ECMP Rebalance\n")
    3313             : {
    3314           0 :         const char *vrfname;
    3315           0 :         char ecmp_xpath[XPATH_MAXLEN];
    3316           0 :         char ecmp_rebalance_xpath[XPATH_MAXLEN];
    3317             : 
    3318           0 :         vrfname = pim_cli_get_vrf_name(vty);
    3319           0 :         if (vrfname == NULL)
    3320             :                 return CMD_WARNING_CONFIG_FAILED;
    3321             : 
    3322           0 :         snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH,
    3323             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    3324           0 :         strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath));
    3325           0 :         snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
    3326             :                  FRR_PIM_VRF_XPATH,
    3327             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    3328           0 :         strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
    3329             :                 sizeof(ecmp_rebalance_xpath));
    3330             : 
    3331           0 :         nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true");
    3332           0 :         nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "true");
    3333             : 
    3334           0 :         return nb_cli_apply_changes(vty, NULL);
    3335             : }
    3336             : 
    3337           0 : DEFUN (no_ip_pim_ecmp_rebalance,
    3338             :        no_ip_pim_ecmp_rebalance_cmd,
    3339             :        "no ip pim ecmp rebalance",
    3340             :        NO_STR
    3341             :        IP_STR
    3342             :        "pim multicast routing\n"
    3343             :        "Disable PIM ECMP \n"
    3344             :        "Disable PIM ECMP Rebalance\n")
    3345             : {
    3346           0 :         const char *vrfname;
    3347           0 :         char ecmp_rebalance_xpath[XPATH_MAXLEN];
    3348             : 
    3349           0 :         vrfname = pim_cli_get_vrf_name(vty);
    3350           0 :         if (vrfname == NULL)
    3351             :                 return CMD_WARNING_CONFIG_FAILED;
    3352             : 
    3353           0 :         snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
    3354             :                  FRR_PIM_VRF_XPATH,
    3355             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    3356           0 :         strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance",
    3357             :                 sizeof(ecmp_rebalance_xpath));
    3358             : 
    3359           0 :         nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "false");
    3360             : 
    3361           0 :         return nb_cli_apply_changes(vty, NULL);
    3362             : }
    3363             : 
    3364           3 : DEFUN (interface_ip_igmp,
    3365             :        interface_ip_igmp_cmd,
    3366             :        "ip igmp",
    3367             :        IP_STR
    3368             :        IFACE_IGMP_STR)
    3369             : {
    3370           3 :         nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
    3371             : 
    3372           3 :         return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
    3373             :                                     "frr-routing:ipv4");
    3374             : }
    3375             : 
    3376           0 : DEFUN (interface_no_ip_igmp,
    3377             :        interface_no_ip_igmp_cmd,
    3378             :        "no ip igmp",
    3379             :        NO_STR
    3380             :        IP_STR
    3381             :        IFACE_IGMP_STR)
    3382             : {
    3383           0 :         const struct lyd_node *pim_enable_dnode;
    3384           0 :         char pim_if_xpath[XPATH_MAXLEN];
    3385             : 
    3386           0 :         int printed =
    3387           0 :                 snprintf(pim_if_xpath, sizeof(pim_if_xpath),
    3388             :                          "%s/frr-pim:pim/address-family[address-family='%s']",
    3389           0 :                          VTY_CURR_XPATH, "frr-routing:ipv4");
    3390             : 
    3391           0 :         if (printed >= (int)(sizeof(pim_if_xpath))) {
    3392           0 :                 vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
    3393             :                         XPATH_MAXLEN);
    3394           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3395             :         }
    3396             : 
    3397           0 :         pim_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
    3398           0 :                                            FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
    3399             :                                            "frr-routing:ipv4");
    3400           0 :         if (!pim_enable_dnode) {
    3401           0 :                 nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY, NULL);
    3402           0 :                 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
    3403             :         } else {
    3404           0 :                 if (!yang_dnode_get_bool(pim_enable_dnode, ".")) {
    3405           0 :                         nb_cli_enqueue_change(vty, pim_if_xpath, NB_OP_DESTROY,
    3406             :                                               NULL);
    3407           0 :                         nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
    3408             :                 } else
    3409           0 :                         nb_cli_enqueue_change(vty, "./enable",
    3410             :                                               NB_OP_MODIFY, "false");
    3411             :         }
    3412             : 
    3413           0 :         return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
    3414             :                                     "frr-routing:ipv4");
    3415             : }
    3416             : 
    3417           0 : DEFUN (interface_ip_igmp_join,
    3418             :        interface_ip_igmp_join_cmd,
    3419             :        "ip igmp join A.B.C.D [A.B.C.D]",
    3420             :        IP_STR
    3421             :        IFACE_IGMP_STR
    3422             :        "IGMP join multicast group\n"
    3423             :        "Multicast group address\n"
    3424             :        "Source address\n")
    3425             : {
    3426           0 :         int idx_group = 3;
    3427           0 :         int idx_source = 4;
    3428           0 :         const char *source_str;
    3429           0 :         char xpath[XPATH_MAXLEN];
    3430             : 
    3431           0 :         if (argc == 5) {
    3432           0 :                 source_str = argv[idx_source]->arg;
    3433             : 
    3434           0 :                 if (strcmp(source_str, "0.0.0.0") == 0) {
    3435           0 :                         vty_out(vty, "Bad source address %s\n",
    3436             :                                 argv[idx_source]->arg);
    3437           0 :                         return CMD_WARNING_CONFIG_FAILED;
    3438             :                 }
    3439             :         } else
    3440             :                 source_str = "0.0.0.0";
    3441             : 
    3442           0 :         snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
    3443           0 :                  "frr-routing:ipv4", argv[idx_group]->arg, source_str);
    3444             : 
    3445           0 :         nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
    3446             : 
    3447           0 :         return nb_cli_apply_changes(vty, NULL);
    3448             : }
    3449             : 
    3450           0 : DEFUN (interface_no_ip_igmp_join,
    3451             :        interface_no_ip_igmp_join_cmd,
    3452             :        "no ip igmp join A.B.C.D [A.B.C.D]",
    3453             :        NO_STR
    3454             :        IP_STR
    3455             :        IFACE_IGMP_STR
    3456             :        "IGMP join multicast group\n"
    3457             :        "Multicast group address\n"
    3458             :        "Source address\n")
    3459             : {
    3460           0 :         int idx_group = 4;
    3461           0 :         int idx_source = 5;
    3462           0 :         const char *source_str;
    3463           0 :         char xpath[XPATH_MAXLEN];
    3464             : 
    3465           0 :         if (argc == 6) {
    3466           0 :                 source_str = argv[idx_source]->arg;
    3467             : 
    3468           0 :                 if (strcmp(source_str, "0.0.0.0") == 0) {
    3469           0 :                         vty_out(vty, "Bad source address %s\n",
    3470             :                                 argv[idx_source]->arg);
    3471           0 :                         return CMD_WARNING_CONFIG_FAILED;
    3472             :                 }
    3473             :         } else
    3474             :                 source_str = "0.0.0.0";
    3475             : 
    3476           0 :         snprintf(xpath, sizeof(xpath), FRR_GMP_JOIN_XPATH,
    3477           0 :                  "frr-routing:ipv4", argv[idx_group]->arg, source_str);
    3478             : 
    3479           0 :         nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
    3480             : 
    3481           0 :         return nb_cli_apply_changes(vty, NULL);
    3482             : }
    3483             : 
    3484           0 : DEFUN (interface_ip_igmp_query_interval,
    3485             :        interface_ip_igmp_query_interval_cmd,
    3486             :        "ip igmp query-interval (1-65535)",
    3487             :        IP_STR
    3488             :        IFACE_IGMP_STR
    3489             :        IFACE_IGMP_QUERY_INTERVAL_STR
    3490             :        "Query interval in seconds\n")
    3491             : {
    3492           0 :         const struct lyd_node *pim_enable_dnode;
    3493             : 
    3494           0 :         pim_enable_dnode =
    3495           0 :                 yang_dnode_getf(vty->candidate_config->dnode,
    3496           0 :                                 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
    3497             :                                 "frr-routing:ipv4");
    3498           0 :         if (!pim_enable_dnode) {
    3499           0 :                 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
    3500             :                                       "true");
    3501             :         } else {
    3502           0 :                 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
    3503           0 :                         nb_cli_enqueue_change(vty, "./enable",
    3504             :                                               NB_OP_MODIFY, "true");
    3505             :         }
    3506             : 
    3507           0 :         nb_cli_enqueue_change(vty, "./query-interval", NB_OP_MODIFY,
    3508           0 :                               argv[3]->arg);
    3509             : 
    3510           0 :         return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
    3511             :                                     "frr-routing:ipv4");
    3512             : }
    3513             : 
    3514           0 : DEFUN (interface_no_ip_igmp_query_interval,
    3515             :        interface_no_ip_igmp_query_interval_cmd,
    3516             :        "no ip igmp query-interval [(1-65535)]",
    3517             :        NO_STR
    3518             :        IP_STR
    3519             :        IFACE_IGMP_STR
    3520             :        IFACE_IGMP_QUERY_INTERVAL_STR
    3521             :        IGNORED_IN_NO_STR)
    3522             : {
    3523           0 :         nb_cli_enqueue_change(vty, "./query-interval", NB_OP_DESTROY, NULL);
    3524             : 
    3525           0 :         return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
    3526             :                                     "frr-routing:ipv4");
    3527             : }
    3528             : 
    3529           0 : DEFUN (interface_ip_igmp_version,
    3530             :        interface_ip_igmp_version_cmd,
    3531             :        "ip igmp version (2-3)",
    3532             :        IP_STR
    3533             :        IFACE_IGMP_STR
    3534             :        "IGMP version\n"
    3535             :        "IGMP version number\n")
    3536             : {
    3537           0 :         nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
    3538             :                               "true");
    3539           0 :         nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_MODIFY,
    3540           0 :                               argv[3]->arg);
    3541             : 
    3542           0 :         return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
    3543             :                                     "frr-routing:ipv4");
    3544             : }
    3545             : 
    3546           0 : DEFUN (interface_no_ip_igmp_version,
    3547             :        interface_no_ip_igmp_version_cmd,
    3548             :        "no ip igmp version (2-3)",
    3549             :        NO_STR
    3550             :        IP_STR
    3551             :        IFACE_IGMP_STR
    3552             :        "IGMP version\n"
    3553             :        "IGMP version number\n")
    3554             : {
    3555           0 :         nb_cli_enqueue_change(vty, "./igmp-version", NB_OP_DESTROY, NULL);
    3556             : 
    3557           0 :         return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
    3558             :                                     "frr-routing:ipv4");
    3559             : }
    3560             : 
    3561           0 : DEFPY (interface_ip_igmp_query_max_response_time,
    3562             :        interface_ip_igmp_query_max_response_time_cmd,
    3563             :        "ip igmp query-max-response-time (1-65535)$qmrt",
    3564             :        IP_STR
    3565             :        IFACE_IGMP_STR
    3566             :        IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
    3567             :        "Query response value in deci-seconds\n")
    3568             : {
    3569           0 :         return gm_process_query_max_response_time_cmd(vty, qmrt_str);
    3570             : }
    3571             : 
    3572           0 : DEFUN (interface_no_ip_igmp_query_max_response_time,
    3573             :        interface_no_ip_igmp_query_max_response_time_cmd,
    3574             :        "no ip igmp query-max-response-time [(1-65535)]",
    3575             :        NO_STR
    3576             :        IP_STR
    3577             :        IFACE_IGMP_STR
    3578             :        IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
    3579             :        IGNORED_IN_NO_STR)
    3580             : {
    3581           0 :         return gm_process_no_query_max_response_time_cmd(vty);
    3582             : }
    3583             : 
    3584           0 : DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
    3585             :               interface_ip_igmp_query_max_response_time_dsec_cmd,
    3586             :               "ip igmp query-max-response-time-dsec (1-65535)",
    3587             :               IP_STR
    3588             :               IFACE_IGMP_STR
    3589             :               IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
    3590             :               "Query response value in deciseconds\n")
    3591             : {
    3592           0 :         const struct lyd_node *pim_enable_dnode;
    3593             : 
    3594           0 :         pim_enable_dnode =
    3595           0 :                 yang_dnode_getf(vty->candidate_config->dnode,
    3596           0 :                                 FRR_PIM_ENABLE_XPATH, VTY_CURR_XPATH,
    3597             :                                 "frr-routing:ipv4");
    3598           0 :         if (!pim_enable_dnode) {
    3599           0 :                 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY,
    3600             :                                       "true");
    3601             :         } else {
    3602           0 :                 if (!yang_dnode_get_bool(pim_enable_dnode, "."))
    3603           0 :                         nb_cli_enqueue_change(vty, "./enable",
    3604             :                                               NB_OP_MODIFY, "true");
    3605             :         }
    3606             : 
    3607           0 :         nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_MODIFY,
    3608           0 :                               argv[3]->arg);
    3609             : 
    3610           0 :         return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
    3611             :                                     "frr-routing:ipv4");
    3612             : }
    3613             : 
    3614           0 : DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
    3615             :               interface_no_ip_igmp_query_max_response_time_dsec_cmd,
    3616             :               "no ip igmp query-max-response-time-dsec [(1-65535)]",
    3617             :               NO_STR
    3618             :               IP_STR
    3619             :               IFACE_IGMP_STR
    3620             :               IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
    3621             :               IGNORED_IN_NO_STR)
    3622             : {
    3623           0 :         nb_cli_enqueue_change(vty, "./query-max-response-time", NB_OP_DESTROY,
    3624             :                               NULL);
    3625             : 
    3626           0 :         return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
    3627             :                                     "frr-routing:ipv4");
    3628             : }
    3629             : 
    3630           0 : DEFPY (interface_ip_igmp_last_member_query_count,
    3631             :        interface_ip_igmp_last_member_query_count_cmd,
    3632             :        "ip igmp last-member-query-count (1-255)$lmqc",
    3633             :        IP_STR
    3634             :        IFACE_IGMP_STR
    3635             :        IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
    3636             :        "Last member query count\n")
    3637             : {
    3638           0 :         return gm_process_last_member_query_count_cmd(vty, lmqc_str);
    3639             : }
    3640             : 
    3641           0 : DEFUN (interface_no_ip_igmp_last_member_query_count,
    3642             :        interface_no_ip_igmp_last_member_query_count_cmd,
    3643             :        "no ip igmp last-member-query-count [(1-255)]",
    3644             :        NO_STR
    3645             :        IP_STR
    3646             :        IFACE_IGMP_STR
    3647             :        IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
    3648             :        IGNORED_IN_NO_STR)
    3649             : {
    3650           0 :         return gm_process_no_last_member_query_count_cmd(vty);
    3651             : }
    3652             : 
    3653           0 : DEFPY (interface_ip_igmp_last_member_query_interval,
    3654             :        interface_ip_igmp_last_member_query_interval_cmd,
    3655             :        "ip igmp last-member-query-interval (1-65535)$lmqi",
    3656             :        IP_STR
    3657             :        IFACE_IGMP_STR
    3658             :        IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
    3659             :        "Last member query interval in deciseconds\n")
    3660             : {
    3661           0 :         return gm_process_last_member_query_interval_cmd(vty, lmqi_str);
    3662             : }
    3663             : 
    3664           0 : DEFUN (interface_no_ip_igmp_last_member_query_interval,
    3665             :        interface_no_ip_igmp_last_member_query_interval_cmd,
    3666             :        "no ip igmp last-member-query-interval [(1-65535)]",
    3667             :        NO_STR
    3668             :        IP_STR
    3669             :        IFACE_IGMP_STR
    3670             :        IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
    3671             :        IGNORED_IN_NO_STR)
    3672             : {
    3673           0 :         return gm_process_no_last_member_query_interval_cmd(vty);
    3674             : }
    3675             : 
    3676           0 : DEFUN (interface_ip_pim_drprio,
    3677             :        interface_ip_pim_drprio_cmd,
    3678             :        "ip pim drpriority (1-4294967295)",
    3679             :        IP_STR
    3680             :        PIM_STR
    3681             :        "Set the Designated Router Election Priority\n"
    3682             :        "Value of the new DR Priority\n")
    3683             : {
    3684           0 :         int idx_number = 3;
    3685             : 
    3686           0 :         return pim_process_ip_pim_drprio_cmd(vty, argv[idx_number]->arg);
    3687             : }
    3688             : 
    3689           0 : DEFUN (interface_no_ip_pim_drprio,
    3690             :        interface_no_ip_pim_drprio_cmd,
    3691             :        "no ip pim drpriority [(1-4294967295)]",
    3692             :        NO_STR
    3693             :        IP_STR
    3694             :        PIM_STR
    3695             :        "Revert the Designated Router Priority to default\n"
    3696             :        "Old Value of the Priority\n")
    3697             : {
    3698           0 :         return pim_process_no_ip_pim_drprio_cmd(vty);
    3699             : }
    3700             : 
    3701           0 : DEFPY_HIDDEN (interface_ip_igmp_query_generate,
    3702             :               interface_ip_igmp_query_generate_cmd,
    3703             :               "ip igmp generate-query-once [version (2-3)]",
    3704             :               IP_STR
    3705             :               IFACE_IGMP_STR
    3706             :               "Generate igmp general query once\n"
    3707             :               "IGMP version\n"
    3708             :               "IGMP version number\n")
    3709             : {
    3710             : #if PIM_IPV == 4
    3711           0 :         VTY_DECLVAR_CONTEXT(interface, ifp);
    3712           0 :         int igmp_version;
    3713           0 :         struct pim_interface *pim_ifp = ifp->info;
    3714             : 
    3715           0 :         if (!ifp->info) {
    3716           0 :                 vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
    3717           0 :                         ifp->name);
    3718           0 :                 return CMD_WARNING_CONFIG_FAILED;
    3719             :         }
    3720             : 
    3721             :         /* It takes the igmp version configured on the interface as default */
    3722           0 :         igmp_version = pim_ifp->igmp_version;
    3723             : 
    3724           0 :         if (argc > 3)
    3725           0 :                 igmp_version = atoi(argv[4]->arg);
    3726             : 
    3727           0 :         igmp_send_query_on_intf(ifp, igmp_version);
    3728             : #endif
    3729           0 :         return CMD_SUCCESS;
    3730             : }
    3731             : 
    3732           0 : DEFPY_HIDDEN (pim_test_sg_keepalive,
    3733             :               pim_test_sg_keepalive_cmd,
    3734             :               "test pim [vrf NAME$name] keepalive-reset A.B.C.D$source A.B.C.D$group",
    3735             :               "Test code\n"
    3736             :               PIM_STR
    3737             :               VRF_CMD_HELP_STR
    3738             :               "Reset the Keepalive Timer\n"
    3739             :               "The Source we are resetting\n"
    3740             :               "The Group we are resetting\n")
    3741             : {
    3742           0 :         struct pim_upstream *up;
    3743           0 :         struct vrf *vrf;
    3744           0 :         struct pim_instance *pim;
    3745           0 :         pim_sgaddr sg;
    3746             : 
    3747           0 :         sg.src = source;
    3748           0 :         sg.grp = group;
    3749             : 
    3750           0 :         vrf = vrf_lookup_by_name(name ? name : VRF_DEFAULT_NAME);
    3751           0 :         if (!vrf) {
    3752           0 :                 vty_out(vty, "%% Vrf specified: %s does not exist\n", name);
    3753           0 :                 return CMD_WARNING;
    3754             :         }
    3755             : 
    3756           0 :         pim = vrf->info;
    3757             : 
    3758           0 :         if (!pim) {
    3759           0 :                 vty_out(vty, "%% Unable to find pim instance\n");
    3760           0 :                 return CMD_WARNING;
    3761             :         }
    3762             : 
    3763           0 :         up = pim_upstream_find(pim, &sg);
    3764           0 :         if (!up) {
    3765           0 :                 vty_out(vty, "%% Unable to find %pSG specified\n", &sg);
    3766           0 :                 return CMD_WARNING;
    3767             :         }
    3768             : 
    3769           0 :         vty_out(vty, "Setting %pSG to current keep alive time: %d\n", &sg,
    3770             :                 pim->keep_alive_time);
    3771           0 :         pim_upstream_keep_alive_timer_start(up, pim->keep_alive_time);
    3772             : 
    3773           0 :         return CMD_SUCCESS;
    3774             : }
    3775             : 
    3776           0 : DEFPY (interface_ip_pim_activeactive,
    3777             :        interface_ip_pim_activeactive_cmd,
    3778             :        "[no$no] ip pim active-active",
    3779             :        NO_STR
    3780             :        IP_STR
    3781             :        PIM_STR
    3782             :        "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n")
    3783             : {
    3784           0 :         return pim_process_ip_pim_activeactive_cmd(vty, no);
    3785             : }
    3786             : 
    3787           0 : DEFUN_HIDDEN (interface_ip_pim_ssm,
    3788             :               interface_ip_pim_ssm_cmd,
    3789             :               "ip pim ssm",
    3790             :               IP_STR
    3791             :               PIM_STR
    3792             :               IFACE_PIM_STR)
    3793             : {
    3794           0 :         int ret;
    3795             : 
    3796           0 :         ret = pim_process_ip_pim_cmd(vty);
    3797             : 
    3798           0 :         if (ret != NB_OK)
    3799             :                 return ret;
    3800             : 
    3801           0 :         vty_out(vty,
    3802             :                 "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed\n");
    3803             : 
    3804           0 :         return NB_OK;
    3805             : }
    3806             : 
    3807           0 : DEFUN_HIDDEN (interface_ip_pim_sm,
    3808             :               interface_ip_pim_sm_cmd,
    3809             :               "ip pim sm",
    3810             :               IP_STR
    3811             :               PIM_STR
    3812             :               IFACE_PIM_SM_STR)
    3813             : {
    3814           0 :         return pim_process_ip_pim_cmd(vty);
    3815             : }
    3816             : 
    3817           6 : DEFPY (interface_ip_pim,
    3818             :        interface_ip_pim_cmd,
    3819             :        "ip pim [passive$passive]",
    3820             :        IP_STR
    3821             :        PIM_STR
    3822             :        "Disable exchange of protocol packets\n")
    3823             : {
    3824           6 :         int ret;
    3825             : 
    3826           6 :         ret = pim_process_ip_pim_cmd(vty);
    3827             : 
    3828           6 :         if (ret != NB_OK)
    3829             :                 return ret;
    3830             : 
    3831           6 :         if (passive)
    3832           0 :                 return pim_process_ip_pim_passive_cmd(vty, true);
    3833             : 
    3834             :         return CMD_SUCCESS;
    3835             : }
    3836             : 
    3837           0 : DEFUN_HIDDEN (interface_no_ip_pim_ssm,
    3838             :               interface_no_ip_pim_ssm_cmd,
    3839             :               "no ip pim ssm",
    3840             :               NO_STR
    3841             :               IP_STR
    3842             :               PIM_STR
    3843             :               IFACE_PIM_STR)
    3844             : {
    3845           0 :         return pim_process_no_ip_pim_cmd(vty);
    3846             : }
    3847             : 
    3848           0 : DEFUN_HIDDEN (interface_no_ip_pim_sm,
    3849             :               interface_no_ip_pim_sm_cmd,
    3850             :               "no ip pim sm",
    3851             :               NO_STR
    3852             :               IP_STR
    3853             :               PIM_STR
    3854             :               IFACE_PIM_SM_STR)
    3855             : {
    3856           0 :         return pim_process_no_ip_pim_cmd(vty);
    3857             : }
    3858             : 
    3859           0 : DEFPY (interface_no_ip_pim,
    3860             :        interface_no_ip_pim_cmd,
    3861             :        "no ip pim [passive$passive]",
    3862             :        NO_STR
    3863             :        IP_STR
    3864             :        PIM_STR
    3865             :        "Disable exchange of protocol packets\n")
    3866             : {
    3867           0 :         if (passive)
    3868           0 :                 return pim_process_ip_pim_passive_cmd(vty, false);
    3869             : 
    3870           0 :         return pim_process_no_ip_pim_cmd(vty);
    3871             : }
    3872             : 
    3873             : /* boundaries */
    3874           0 : DEFUN(interface_ip_pim_boundary_oil,
    3875             :       interface_ip_pim_boundary_oil_cmd,
    3876             :       "ip multicast boundary oil WORD",
    3877             :       IP_STR
    3878             :       "Generic multicast configuration options\n"
    3879             :       "Define multicast boundary\n"
    3880             :       "Filter OIL by group using prefix list\n"
    3881             :       "Prefix list to filter OIL with\n")
    3882             : {
    3883           0 :         return pim_process_ip_pim_boundary_oil_cmd(vty, argv[4]->arg);
    3884             : }
    3885             : 
    3886           0 : DEFUN(interface_no_ip_pim_boundary_oil,
    3887             :       interface_no_ip_pim_boundary_oil_cmd,
    3888             :       "no ip multicast boundary oil [WORD]",
    3889             :       NO_STR
    3890             :       IP_STR
    3891             :       "Generic multicast configuration options\n"
    3892             :       "Define multicast boundary\n"
    3893             :       "Filter OIL by group using prefix list\n"
    3894             :       "Prefix list to filter OIL with\n")
    3895             : {
    3896           0 :         return pim_process_no_ip_pim_boundary_oil_cmd(vty);
    3897             : }
    3898             : 
    3899           0 : DEFUN (interface_ip_mroute,
    3900             :        interface_ip_mroute_cmd,
    3901             :        "ip mroute INTERFACE A.B.C.D [A.B.C.D]",
    3902             :        IP_STR
    3903             :        "Add multicast route\n"
    3904             :        "Outgoing interface name\n"
    3905             :        "Group address\n"
    3906             :        "Source address\n")
    3907             : {
    3908           0 :         int idx_interface = 2;
    3909           0 :         int idx_ipv4 = 3;
    3910           0 :         const char *source_str;
    3911             : 
    3912           0 :         if (argc == (idx_ipv4 + 1))
    3913             :                 source_str = "0.0.0.0";
    3914             :         else
    3915           0 :                 source_str = argv[idx_ipv4 + 1]->arg;
    3916             : 
    3917           0 :         return pim_process_ip_mroute_cmd(vty, argv[idx_interface]->arg,
    3918           0 :                                          argv[idx_ipv4]->arg, source_str);
    3919             : }
    3920             : 
    3921           0 : DEFUN (interface_no_ip_mroute,
    3922             :        interface_no_ip_mroute_cmd,
    3923             :        "no ip mroute INTERFACE A.B.C.D [A.B.C.D]",
    3924             :        NO_STR
    3925             :        IP_STR
    3926             :        "Add multicast route\n"
    3927             :        "Outgoing interface name\n"
    3928             :        "Group Address\n"
    3929             :        "Source Address\n")
    3930             : {
    3931           0 :         int idx_interface = 3;
    3932           0 :         int idx_ipv4 = 4;
    3933           0 :         const char *source_str;
    3934             : 
    3935           0 :         if (argc == (idx_ipv4 + 1))
    3936             :                 source_str = "0.0.0.0";
    3937             :         else
    3938           0 :                 source_str = argv[idx_ipv4 + 1]->arg;
    3939             : 
    3940           0 :         return pim_process_no_ip_mroute_cmd(vty, argv[idx_interface]->arg,
    3941           0 :                                             argv[idx_ipv4]->arg, source_str);
    3942             : }
    3943             : 
    3944           3 : DEFUN (interface_ip_pim_hello,
    3945             :        interface_ip_pim_hello_cmd,
    3946             :        "ip pim hello (1-65535) [(1-65535)]",
    3947             :        IP_STR
    3948             :        PIM_STR
    3949             :        IFACE_PIM_HELLO_STR
    3950             :        IFACE_PIM_HELLO_TIME_STR
    3951             :        IFACE_PIM_HELLO_HOLD_STR)
    3952             : {
    3953           3 :         int idx_time = 3;
    3954           3 :         int idx_hold = 4;
    3955             : 
    3956           3 :         if (argc == idx_hold + 1)
    3957           3 :                 return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
    3958           3 :                                                     argv[idx_hold]->arg);
    3959             : 
    3960             :         else
    3961           0 :                 return pim_process_ip_pim_hello_cmd(vty, argv[idx_time]->arg,
    3962             :                                                     NULL);
    3963             : }
    3964             : 
    3965           0 : DEFUN (interface_no_ip_pim_hello,
    3966             :        interface_no_ip_pim_hello_cmd,
    3967             :        "no ip pim hello [(1-65535) [(1-65535)]]",
    3968             :        NO_STR
    3969             :        IP_STR
    3970             :        PIM_STR
    3971             :        IFACE_PIM_HELLO_STR
    3972             :        IGNORED_IN_NO_STR
    3973             :        IGNORED_IN_NO_STR)
    3974             : {
    3975           0 :         return pim_process_no_ip_pim_hello_cmd(vty);
    3976             : }
    3977             : 
    3978           0 : DEFUN (debug_igmp,
    3979             :        debug_igmp_cmd,
    3980             :        "debug igmp",
    3981             :        DEBUG_STR
    3982             :        DEBUG_IGMP_STR)
    3983             : {
    3984           0 :         PIM_DO_DEBUG_GM_EVENTS;
    3985           0 :         PIM_DO_DEBUG_GM_PACKETS;
    3986           0 :         PIM_DO_DEBUG_GM_TRACE;
    3987           0 :         return CMD_SUCCESS;
    3988             : }
    3989             : 
    3990           0 : DEFUN (no_debug_igmp,
    3991             :        no_debug_igmp_cmd,
    3992             :        "no debug igmp",
    3993             :        NO_STR
    3994             :        DEBUG_STR
    3995             :        DEBUG_IGMP_STR)
    3996             : {
    3997           0 :         PIM_DONT_DEBUG_GM_EVENTS;
    3998           0 :         PIM_DONT_DEBUG_GM_PACKETS;
    3999           0 :         PIM_DONT_DEBUG_GM_TRACE;
    4000           0 :         return CMD_SUCCESS;
    4001             : }
    4002             : 
    4003             : 
    4004           0 : DEFUN (debug_igmp_events,
    4005             :        debug_igmp_events_cmd,
    4006             :        "debug igmp events",
    4007             :        DEBUG_STR
    4008             :        DEBUG_IGMP_STR
    4009             :        DEBUG_IGMP_EVENTS_STR)
    4010             : {
    4011           0 :         PIM_DO_DEBUG_GM_EVENTS;
    4012           0 :         return CMD_SUCCESS;
    4013             : }
    4014             : 
    4015           0 : DEFUN (no_debug_igmp_events,
    4016             :        no_debug_igmp_events_cmd,
    4017             :        "no debug igmp events",
    4018             :        NO_STR
    4019             :        DEBUG_STR
    4020             :        DEBUG_IGMP_STR
    4021             :        DEBUG_IGMP_EVENTS_STR)
    4022             : {
    4023           0 :         PIM_DONT_DEBUG_GM_EVENTS;
    4024           0 :         return CMD_SUCCESS;
    4025             : }
    4026             : 
    4027             : 
    4028           0 : DEFUN (debug_igmp_packets,
    4029             :        debug_igmp_packets_cmd,
    4030             :        "debug igmp packets",
    4031             :        DEBUG_STR
    4032             :        DEBUG_IGMP_STR
    4033             :        DEBUG_IGMP_PACKETS_STR)
    4034             : {
    4035           0 :         PIM_DO_DEBUG_GM_PACKETS;
    4036           0 :         return CMD_SUCCESS;
    4037             : }
    4038             : 
    4039           0 : DEFUN (no_debug_igmp_packets,
    4040             :        no_debug_igmp_packets_cmd,
    4041             :        "no debug igmp packets",
    4042             :        NO_STR
    4043             :        DEBUG_STR
    4044             :        DEBUG_IGMP_STR
    4045             :        DEBUG_IGMP_PACKETS_STR)
    4046             : {
    4047           0 :         PIM_DONT_DEBUG_GM_PACKETS;
    4048           0 :         return CMD_SUCCESS;
    4049             : }
    4050             : 
    4051             : 
    4052           0 : DEFUN (debug_igmp_trace,
    4053             :        debug_igmp_trace_cmd,
    4054             :        "debug igmp trace",
    4055             :        DEBUG_STR
    4056             :        DEBUG_IGMP_STR
    4057             :        DEBUG_IGMP_TRACE_STR)
    4058             : {
    4059           0 :         PIM_DO_DEBUG_GM_TRACE;
    4060           0 :         return CMD_SUCCESS;
    4061             : }
    4062             : 
    4063           0 : DEFUN (no_debug_igmp_trace,
    4064             :        no_debug_igmp_trace_cmd,
    4065             :        "no debug igmp trace",
    4066             :        NO_STR
    4067             :        DEBUG_STR
    4068             :        DEBUG_IGMP_STR
    4069             :        DEBUG_IGMP_TRACE_STR)
    4070             : {
    4071           0 :         PIM_DONT_DEBUG_GM_TRACE;
    4072           0 :         return CMD_SUCCESS;
    4073             : }
    4074             : 
    4075             : 
    4076           0 : DEFUN (debug_igmp_trace_detail,
    4077             :        debug_igmp_trace_detail_cmd,
    4078             :        "debug igmp trace detail",
    4079             :        DEBUG_STR
    4080             :        DEBUG_IGMP_STR
    4081             :        DEBUG_IGMP_TRACE_STR
    4082             :        "detailed\n")
    4083             : {
    4084           0 :         PIM_DO_DEBUG_GM_TRACE_DETAIL;
    4085           0 :         return CMD_SUCCESS;
    4086             : }
    4087             : 
    4088           0 : DEFUN (no_debug_igmp_trace_detail,
    4089             :        no_debug_igmp_trace_detail_cmd,
    4090             :        "no debug igmp trace detail",
    4091             :        NO_STR
    4092             :        DEBUG_STR
    4093             :        DEBUG_IGMP_STR
    4094             :        DEBUG_IGMP_TRACE_STR
    4095             :        "detailed\n")
    4096             : {
    4097           0 :         PIM_DONT_DEBUG_GM_TRACE_DETAIL;
    4098           0 :         return CMD_SUCCESS;
    4099             : }
    4100             : 
    4101             : 
    4102           0 : DEFUN (debug_mroute,
    4103             :        debug_mroute_cmd,
    4104             :        "debug mroute",
    4105             :        DEBUG_STR
    4106             :        DEBUG_MROUTE_STR)
    4107             : {
    4108           0 :         PIM_DO_DEBUG_MROUTE;
    4109           0 :         return CMD_SUCCESS;
    4110             : }
    4111             : 
    4112           0 : DEFUN (debug_mroute_detail,
    4113             :        debug_mroute_detail_cmd,
    4114             :        "debug mroute detail",
    4115             :        DEBUG_STR
    4116             :        DEBUG_MROUTE_STR
    4117             :        "detailed\n")
    4118             : {
    4119           0 :         PIM_DO_DEBUG_MROUTE_DETAIL;
    4120           0 :         return CMD_SUCCESS;
    4121             : }
    4122             : 
    4123           0 : DEFUN (no_debug_mroute,
    4124             :        no_debug_mroute_cmd,
    4125             :        "no debug mroute",
    4126             :        NO_STR
    4127             :        DEBUG_STR
    4128             :        DEBUG_MROUTE_STR)
    4129             : {
    4130           0 :         PIM_DONT_DEBUG_MROUTE;
    4131           0 :         return CMD_SUCCESS;
    4132             : }
    4133             : 
    4134           0 : DEFUN (no_debug_mroute_detail,
    4135             :        no_debug_mroute_detail_cmd,
    4136             :        "no debug mroute detail",
    4137             :        NO_STR
    4138             :        DEBUG_STR
    4139             :        DEBUG_MROUTE_STR
    4140             :        "detailed\n")
    4141             : {
    4142           0 :         PIM_DONT_DEBUG_MROUTE_DETAIL;
    4143           0 :         return CMD_SUCCESS;
    4144             : }
    4145             : 
    4146           0 : DEFUN (debug_pim_static,
    4147             :        debug_pim_static_cmd,
    4148             :        "debug pim static",
    4149             :        DEBUG_STR
    4150             :        DEBUG_PIM_STR
    4151             :        DEBUG_STATIC_STR)
    4152             : {
    4153           0 :         PIM_DO_DEBUG_STATIC;
    4154           0 :         return CMD_SUCCESS;
    4155             : }
    4156             : 
    4157           0 : DEFUN (no_debug_pim_static,
    4158             :        no_debug_pim_static_cmd,
    4159             :        "no debug pim static",
    4160             :        NO_STR
    4161             :        DEBUG_STR
    4162             :        DEBUG_PIM_STR
    4163             :        DEBUG_STATIC_STR)
    4164             : {
    4165           0 :         PIM_DONT_DEBUG_STATIC;
    4166           0 :         return CMD_SUCCESS;
    4167             : }
    4168             : 
    4169             : 
    4170           0 : DEFPY (debug_pim,
    4171             :        debug_pim_cmd,
    4172             :        "[no] debug pim",
    4173             :        NO_STR
    4174             :        DEBUG_STR
    4175             :        DEBUG_PIM_STR)
    4176             : {
    4177           0 :         if (!no)
    4178           0 :                 return pim_debug_pim_cmd();
    4179             :         else
    4180           0 :                 return pim_no_debug_pim_cmd();
    4181             : }
    4182             : 
    4183           0 : DEFPY (debug_pim_nht,
    4184             :        debug_pim_nht_cmd,
    4185             :        "[no] debug pim nht",
    4186             :        NO_STR
    4187             :        DEBUG_STR
    4188             :        DEBUG_PIM_STR
    4189             :        "Nexthop Tracking\n")
    4190             : {
    4191           0 :         if (!no)
    4192           0 :                 PIM_DO_DEBUG_PIM_NHT;
    4193             :         else
    4194           0 :                 PIM_DONT_DEBUG_PIM_NHT;
    4195           0 :         return CMD_SUCCESS;
    4196             : }
    4197             : 
    4198           0 : DEFPY (debug_pim_nht_det,
    4199             :        debug_pim_nht_det_cmd,
    4200             :        "[no] debug pim nht detail",
    4201             :        NO_STR
    4202             :        DEBUG_STR
    4203             :        DEBUG_PIM_STR
    4204             :        "Nexthop Tracking\n"
    4205             :        "Detailed Information\n")
    4206             : {
    4207           0 :         if (!no)
    4208           0 :                 PIM_DO_DEBUG_PIM_NHT_DETAIL;
    4209             :         else
    4210           0 :                 PIM_DONT_DEBUG_PIM_NHT_DETAIL;
    4211           0 :         return CMD_SUCCESS;
    4212             : }
    4213             : 
    4214           0 : DEFUN (debug_pim_nht_rp,
    4215             :        debug_pim_nht_rp_cmd,
    4216             :        "debug pim nht rp",
    4217             :        DEBUG_STR
    4218             :        DEBUG_PIM_STR
    4219             :        "Nexthop Tracking\n"
    4220             :        "RP Nexthop Tracking\n")
    4221             : {
    4222           0 :         PIM_DO_DEBUG_PIM_NHT_RP;
    4223           0 :         return CMD_SUCCESS;
    4224             : }
    4225             : 
    4226           0 : DEFUN (no_debug_pim_nht_rp,
    4227             :        no_debug_pim_nht_rp_cmd,
    4228             :        "no debug pim nht rp",
    4229             :        NO_STR
    4230             :        DEBUG_STR
    4231             :        DEBUG_PIM_STR
    4232             :        "Nexthop Tracking\n"
    4233             :        "RP Nexthop Tracking\n")
    4234             : {
    4235           0 :         PIM_DONT_DEBUG_PIM_NHT_RP;
    4236           0 :         return CMD_SUCCESS;
    4237             : }
    4238             : 
    4239           0 : DEFPY (debug_pim_events,
    4240             :        debug_pim_events_cmd,
    4241             :        "[no] debug pim events",
    4242             :        NO_STR
    4243             :        DEBUG_STR
    4244             :        DEBUG_PIM_STR
    4245             :        DEBUG_PIM_EVENTS_STR)
    4246             : {
    4247           0 :         if (!no)
    4248           0 :                 PIM_DO_DEBUG_PIM_EVENTS;
    4249             :         else
    4250           0 :                 PIM_DONT_DEBUG_PIM_EVENTS;
    4251           0 :         return CMD_SUCCESS;
    4252             : }
    4253             : 
    4254           0 : DEFPY (debug_pim_packets,
    4255             :        debug_pim_packets_cmd,
    4256             :        "[no] debug pim packets [<hello$hello|joins$joins|register$registers>]",
    4257             :        NO_STR DEBUG_STR
    4258             :        DEBUG_PIM_STR
    4259             :        DEBUG_PIM_PACKETS_STR
    4260             :        DEBUG_PIM_HELLO_PACKETS_STR
    4261             :        DEBUG_PIM_J_P_PACKETS_STR
    4262             :        DEBUG_PIM_PIM_REG_PACKETS_STR)
    4263             : {
    4264           0 :         if (!no)
    4265           0 :                 return pim_debug_pim_packets_cmd(hello, joins, registers, vty);
    4266             :         else
    4267           0 :                 return pim_no_debug_pim_packets_cmd(hello, joins, registers,
    4268             :                                                     vty);
    4269             : }
    4270             : 
    4271           0 : DEFPY (debug_pim_packetdump_send,
    4272             :        debug_pim_packetdump_send_cmd,
    4273             :        "[no] debug pim packet-dump send",
    4274             :        NO_STR
    4275             :        DEBUG_STR
    4276             :        DEBUG_PIM_STR
    4277             :        DEBUG_PIM_PACKETDUMP_STR
    4278             :        DEBUG_PIM_PACKETDUMP_SEND_STR)
    4279             : {
    4280           0 :         if (!no)
    4281           0 :                 PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
    4282             :         else
    4283           0 :                 PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
    4284           0 :         return CMD_SUCCESS;
    4285             : }
    4286             : 
    4287           0 : DEFPY (debug_pim_packetdump_recv,
    4288             :        debug_pim_packetdump_recv_cmd,
    4289             :        "[no] debug pim packet-dump receive",
    4290             :        NO_STR
    4291             :        DEBUG_STR
    4292             :        DEBUG_PIM_STR
    4293             :        DEBUG_PIM_PACKETDUMP_STR
    4294             :        DEBUG_PIM_PACKETDUMP_RECV_STR)
    4295             : {
    4296           0 :         if (!no)
    4297           0 :                 PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
    4298             :         else
    4299           0 :                 PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
    4300           0 :         return CMD_SUCCESS;
    4301             : }
    4302             : 
    4303           0 : DEFPY (debug_pim_trace,
    4304             :        debug_pim_trace_cmd,
    4305             :        "[no] debug pim trace",
    4306             :        NO_STR
    4307             :        DEBUG_STR
    4308             :        DEBUG_PIM_STR
    4309             :        DEBUG_PIM_TRACE_STR)
    4310             : {
    4311           0 :         if (!no)
    4312           0 :                 PIM_DO_DEBUG_PIM_TRACE;
    4313             :         else
    4314           0 :                 PIM_DONT_DEBUG_PIM_TRACE;
    4315           0 :         return CMD_SUCCESS;
    4316             : }
    4317             : 
    4318           0 : DEFPY (debug_pim_trace_detail,
    4319             :        debug_pim_trace_detail_cmd,
    4320             :        "[no] debug pim trace detail",
    4321             :        NO_STR
    4322             :        DEBUG_STR
    4323             :        DEBUG_PIM_STR
    4324             :        DEBUG_PIM_TRACE_STR
    4325             :        "Detailed Information\n")
    4326             : {
    4327           0 :         if (!no)
    4328           0 :                 PIM_DO_DEBUG_PIM_TRACE_DETAIL;
    4329             :         else
    4330           0 :                 PIM_DONT_DEBUG_PIM_TRACE_DETAIL;
    4331           0 :         return CMD_SUCCESS;
    4332             : }
    4333             : 
    4334           0 : DEFUN (debug_ssmpingd,
    4335             :        debug_ssmpingd_cmd,
    4336             :        "debug ssmpingd",
    4337             :        DEBUG_STR
    4338             :        DEBUG_SSMPINGD_STR)
    4339             : {
    4340           0 :         PIM_DO_DEBUG_SSMPINGD;
    4341           0 :         return CMD_SUCCESS;
    4342             : }
    4343             : 
    4344           0 : DEFUN (no_debug_ssmpingd,
    4345             :        no_debug_ssmpingd_cmd,
    4346             :        "no debug ssmpingd",
    4347             :        NO_STR
    4348             :        DEBUG_STR
    4349             :        DEBUG_SSMPINGD_STR)
    4350             : {
    4351           0 :         PIM_DONT_DEBUG_SSMPINGD;
    4352           0 :         return CMD_SUCCESS;
    4353             : }
    4354             : 
    4355           0 : DEFPY (debug_pim_zebra,
    4356             :        debug_pim_zebra_cmd,
    4357             :        "[no] debug pim zebra",
    4358             :        NO_STR
    4359             :        DEBUG_STR
    4360             :        DEBUG_PIM_STR
    4361             :        DEBUG_PIM_ZEBRA_STR)
    4362             : {
    4363           0 :         if (!no)
    4364           0 :                 PIM_DO_DEBUG_ZEBRA;
    4365             :         else
    4366           0 :                 PIM_DONT_DEBUG_ZEBRA;
    4367           0 :         return CMD_SUCCESS;
    4368             : }
    4369             : 
    4370           0 : DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag",
    4371             :       DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
    4372             : {
    4373           0 :         PIM_DO_DEBUG_MLAG;
    4374           0 :         return CMD_SUCCESS;
    4375             : }
    4376             : 
    4377           0 : DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag",
    4378             :       NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR)
    4379             : {
    4380           0 :         PIM_DONT_DEBUG_MLAG;
    4381           0 :         return CMD_SUCCESS;
    4382             : }
    4383             : 
    4384           0 : DEFUN (debug_pim_vxlan,
    4385             :        debug_pim_vxlan_cmd,
    4386             :        "debug pim vxlan",
    4387             :        DEBUG_STR
    4388             :        DEBUG_PIM_STR
    4389             :        DEBUG_PIM_VXLAN_STR)
    4390             : {
    4391           0 :         PIM_DO_DEBUG_VXLAN;
    4392           0 :         return CMD_SUCCESS;
    4393             : }
    4394             : 
    4395           0 : DEFUN (no_debug_pim_vxlan,
    4396             :        no_debug_pim_vxlan_cmd,
    4397             :        "no debug pim vxlan",
    4398             :        NO_STR
    4399             :        DEBUG_STR
    4400             :        DEBUG_PIM_STR
    4401             :        DEBUG_PIM_VXLAN_STR)
    4402             : {
    4403           0 :         PIM_DONT_DEBUG_VXLAN;
    4404           0 :         return CMD_SUCCESS;
    4405             : }
    4406             : 
    4407           0 : DEFUN (debug_msdp,
    4408             :        debug_msdp_cmd,
    4409             :        "debug msdp",
    4410             :        DEBUG_STR
    4411             :        DEBUG_MSDP_STR)
    4412             : {
    4413           0 :         PIM_DO_DEBUG_MSDP_EVENTS;
    4414           0 :         PIM_DO_DEBUG_MSDP_PACKETS;
    4415           0 :         return CMD_SUCCESS;
    4416             : }
    4417             : 
    4418           0 : DEFUN (no_debug_msdp,
    4419             :        no_debug_msdp_cmd,
    4420             :        "no debug msdp",
    4421             :        NO_STR
    4422             :        DEBUG_STR
    4423             :        DEBUG_MSDP_STR)
    4424             : {
    4425           0 :         PIM_DONT_DEBUG_MSDP_EVENTS;
    4426           0 :         PIM_DONT_DEBUG_MSDP_PACKETS;
    4427           0 :         return CMD_SUCCESS;
    4428             : }
    4429             : 
    4430           0 : DEFUN (debug_msdp_events,
    4431             :        debug_msdp_events_cmd,
    4432             :        "debug msdp events",
    4433             :        DEBUG_STR
    4434             :        DEBUG_MSDP_STR
    4435             :        DEBUG_MSDP_EVENTS_STR)
    4436             : {
    4437           0 :         PIM_DO_DEBUG_MSDP_EVENTS;
    4438           0 :         return CMD_SUCCESS;
    4439             : }
    4440             : 
    4441           0 : DEFUN (no_debug_msdp_events,
    4442             :        no_debug_msdp_events_cmd,
    4443             :        "no debug msdp events",
    4444             :        NO_STR
    4445             :        DEBUG_STR
    4446             :        DEBUG_MSDP_STR
    4447             :        DEBUG_MSDP_EVENTS_STR)
    4448             : {
    4449           0 :         PIM_DONT_DEBUG_MSDP_EVENTS;
    4450           0 :         return CMD_SUCCESS;
    4451             : }
    4452             : 
    4453           0 : DEFUN (debug_msdp_packets,
    4454             :        debug_msdp_packets_cmd,
    4455             :        "debug msdp packets",
    4456             :        DEBUG_STR
    4457             :        DEBUG_MSDP_STR
    4458             :        DEBUG_MSDP_PACKETS_STR)
    4459             : {
    4460           0 :         PIM_DO_DEBUG_MSDP_PACKETS;
    4461           0 :         return CMD_SUCCESS;
    4462             : }
    4463             : 
    4464           0 : DEFUN (no_debug_msdp_packets,
    4465             :        no_debug_msdp_packets_cmd,
    4466             :        "no debug msdp packets",
    4467             :        NO_STR
    4468             :        DEBUG_STR
    4469             :        DEBUG_MSDP_STR
    4470             :        DEBUG_MSDP_PACKETS_STR)
    4471             : {
    4472           0 :         PIM_DONT_DEBUG_MSDP_PACKETS;
    4473           0 :         return CMD_SUCCESS;
    4474             : }
    4475             : 
    4476           0 : DEFUN (debug_mtrace,
    4477             :        debug_mtrace_cmd,
    4478             :        "debug mtrace",
    4479             :        DEBUG_STR
    4480             :        DEBUG_MTRACE_STR)
    4481             : {
    4482           0 :         PIM_DO_DEBUG_MTRACE;
    4483           0 :         return CMD_SUCCESS;
    4484             : }
    4485             : 
    4486           0 : DEFUN (no_debug_mtrace,
    4487             :        no_debug_mtrace_cmd,
    4488             :        "no debug mtrace",
    4489             :        NO_STR
    4490             :        DEBUG_STR
    4491             :        DEBUG_MTRACE_STR)
    4492             : {
    4493           0 :         PIM_DONT_DEBUG_MTRACE;
    4494           0 :         return CMD_SUCCESS;
    4495             : }
    4496             : 
    4497           3 : DEFUN (debug_bsm,
    4498             :        debug_bsm_cmd,
    4499             :        "debug pim bsm",
    4500             :        DEBUG_STR
    4501             :        DEBUG_PIM_STR
    4502             :        DEBUG_PIM_BSM_STR)
    4503             : {
    4504           3 :         PIM_DO_DEBUG_BSM;
    4505           3 :         return CMD_SUCCESS;
    4506             : }
    4507             : 
    4508           0 : DEFUN (no_debug_bsm,
    4509             :        no_debug_bsm_cmd,
    4510             :        "no debug pim bsm",
    4511             :        NO_STR
    4512             :        DEBUG_STR
    4513             :        DEBUG_PIM_STR
    4514             :        DEBUG_PIM_BSM_STR)
    4515             : {
    4516           0 :         PIM_DONT_DEBUG_BSM;
    4517           0 :         return CMD_SUCCESS;
    4518             : }
    4519             : 
    4520             : 
    4521           0 : DEFUN_NOSH (show_debugging_pim,
    4522             :             show_debugging_pim_cmd,
    4523             :             "show debugging [pim]",
    4524             :             SHOW_STR
    4525             :             DEBUG_STR
    4526             :             PIM_STR)
    4527             : {
    4528           0 :         vty_out(vty, "PIM debugging status\n");
    4529             : 
    4530           0 :         pim_debug_config_write(vty);
    4531             : 
    4532           0 :         cmd_show_lib_debugs(vty);
    4533           0 :         return CMD_SUCCESS;
    4534             : }
    4535             : 
    4536           0 : DEFUN (interface_pim_use_source,
    4537             :        interface_pim_use_source_cmd,
    4538             :        "ip pim use-source A.B.C.D",
    4539             :        IP_STR
    4540             :        PIM_STR
    4541             :        "Configure primary IP address\n"
    4542             :        "source ip address\n")
    4543             : {
    4544           0 :         nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, argv[3]->arg);
    4545             : 
    4546           0 :         return nb_cli_apply_changes(vty,
    4547             :                                     FRR_PIM_INTERFACE_XPATH,
    4548             :                                     "frr-routing:ipv4");
    4549             : }
    4550             : 
    4551           0 : DEFUN (interface_no_pim_use_source,
    4552             :        interface_no_pim_use_source_cmd,
    4553             :        "no ip pim use-source [A.B.C.D]",
    4554             :        NO_STR
    4555             :        IP_STR
    4556             :        PIM_STR
    4557             :        "Delete source IP address\n"
    4558             :        "source ip address\n")
    4559             : {
    4560           0 :         nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, "0.0.0.0");
    4561             : 
    4562           0 :         return nb_cli_apply_changes(vty,
    4563             :                                     FRR_PIM_INTERFACE_XPATH,
    4564             :                                     "frr-routing:ipv4");
    4565             : }
    4566             : 
    4567           0 : DEFPY (ip_pim_bfd,
    4568             :        ip_pim_bfd_cmd,
    4569             :        "ip pim bfd [profile BFDPROF$prof]",
    4570             :        IP_STR
    4571             :        PIM_STR
    4572             :        "Enables BFD support\n"
    4573             :        "Use BFD profile\n"
    4574             :        "Use BFD profile name\n")
    4575             : {
    4576           0 :         const struct lyd_node *igmp_enable_dnode;
    4577             : 
    4578           0 :         igmp_enable_dnode =
    4579           0 :                 yang_dnode_getf(vty->candidate_config->dnode,
    4580           0 :                                 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
    4581             :                                 "frr-routing:ipv4");
    4582           0 :         if (!igmp_enable_dnode)
    4583           0 :                 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
    4584             :                                       "true");
    4585             :         else {
    4586           0 :                 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
    4587           0 :                         nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
    4588             :                                               "true");
    4589             :         }
    4590             : 
    4591           0 :         nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
    4592           0 :         if (prof)
    4593           0 :                 nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_MODIFY, prof);
    4594             : 
    4595           0 :         return nb_cli_apply_changes(vty,
    4596             :                                     FRR_PIM_INTERFACE_XPATH,
    4597             :                                     "frr-routing:ipv4");
    4598             : }
    4599             : 
    4600           0 : DEFPY(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd,
    4601             :       "no ip pim bfd profile [BFDPROF]",
    4602             :       NO_STR
    4603             :       IP_STR
    4604             :       PIM_STR
    4605             :       "Enables BFD support\n"
    4606             :       "Disable BFD profile\n"
    4607             :       "BFD Profile name\n")
    4608             : {
    4609           0 :         nb_cli_enqueue_change(vty, "./bfd/profile", NB_OP_DESTROY, NULL);
    4610             : 
    4611           0 :         return nb_cli_apply_changes(vty,
    4612             :                         FRR_PIM_INTERFACE_XPATH,
    4613             :                         "frr-routing:ipv4");
    4614             : }
    4615             : 
    4616           0 : DEFUN (no_ip_pim_bfd,
    4617             :        no_ip_pim_bfd_cmd,
    4618             :        "no ip pim bfd",
    4619             :        NO_STR
    4620             :        IP_STR
    4621             :        PIM_STR
    4622             :        "Disables BFD support\n")
    4623             : {
    4624           0 :         nb_cli_enqueue_change(vty, "./bfd", NB_OP_DESTROY, NULL);
    4625             : 
    4626           0 :         return nb_cli_apply_changes(vty,
    4627             :                         FRR_PIM_INTERFACE_XPATH,
    4628             :                         "frr-routing:ipv4");
    4629             : }
    4630             : 
    4631           0 : DEFUN (ip_pim_bsm,
    4632             :        ip_pim_bsm_cmd,
    4633             :        "ip pim bsm",
    4634             :        IP_STR
    4635             :        PIM_STR
    4636             :        "Enable BSM support on the interface\n")
    4637             : {
    4638           0 :         return pim_process_bsm_cmd(vty);
    4639             : }
    4640           0 : DEFUN (no_ip_pim_bsm,
    4641             :        no_ip_pim_bsm_cmd,
    4642             :        "no ip pim bsm",
    4643             :        NO_STR
    4644             :        IP_STR
    4645             :        PIM_STR
    4646             :        "Enable BSM support on the interface\n")
    4647             : {
    4648           0 :         return pim_process_no_bsm_cmd(vty);
    4649             : }
    4650             : 
    4651           0 : DEFUN (ip_pim_ucast_bsm,
    4652             :        ip_pim_ucast_bsm_cmd,
    4653             :        "ip pim unicast-bsm",
    4654             :        IP_STR
    4655             :        PIM_STR
    4656             :        "Accept/Send unicast BSM on the interface\n")
    4657             : {
    4658           0 :         return pim_process_unicast_bsm_cmd(vty);
    4659             : }
    4660             : 
    4661           0 : DEFUN (no_ip_pim_ucast_bsm,
    4662             :        no_ip_pim_ucast_bsm_cmd,
    4663             :        "no ip pim unicast-bsm",
    4664             :        NO_STR
    4665             :        IP_STR
    4666             :        PIM_STR
    4667             :        "Accept/Send unicast BSM on the interface\n")
    4668             : {
    4669           0 :         return pim_process_no_unicast_bsm_cmd(vty);
    4670             : }
    4671             : 
    4672             : #if HAVE_BFDD > 0
    4673           0 : DEFUN_HIDDEN (
    4674             :         ip_pim_bfd_param,
    4675             :         ip_pim_bfd_param_cmd,
    4676             :         "ip pim bfd (2-255) (1-65535) (1-65535)",
    4677             :         IP_STR
    4678             :         PIM_STR
    4679             :         "Enables BFD support\n"
    4680             :         "Detect Multiplier\n"
    4681             :         "Required min receive interval\n"
    4682             :         "Desired min transmit interval\n")
    4683             : #else
    4684             :         DEFUN(
    4685             :                 ip_pim_bfd_param,
    4686             :                 ip_pim_bfd_param_cmd,
    4687             :                 "ip pim bfd (2-255) (1-65535) (1-65535)",
    4688             :                 IP_STR
    4689             :                 PIM_STR
    4690             :                 "Enables BFD support\n"
    4691             :                 "Detect Multiplier\n"
    4692             :                 "Required min receive interval\n"
    4693             :                 "Desired min transmit interval\n")
    4694             : #endif /* HAVE_BFDD */
    4695             : {
    4696           0 :         int idx_number = 3;
    4697           0 :         int idx_number_2 = 4;
    4698           0 :         int idx_number_3 = 5;
    4699           0 :         const struct lyd_node *igmp_enable_dnode;
    4700             : 
    4701           0 :         igmp_enable_dnode =
    4702           0 :                 yang_dnode_getf(vty->candidate_config->dnode,
    4703           0 :                                 FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
    4704             :                                 "frr-routing:ipv4");
    4705           0 :         if (!igmp_enable_dnode)
    4706           0 :                 nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
    4707             :                                       "true");
    4708             :         else {
    4709           0 :                 if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
    4710           0 :                         nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
    4711             :                                               "true");
    4712             :         }
    4713             : 
    4714           0 :         nb_cli_enqueue_change(vty, "./bfd", NB_OP_CREATE, NULL);
    4715           0 :         nb_cli_enqueue_change(vty, "./bfd/min-rx-interval", NB_OP_MODIFY,
    4716           0 :                               argv[idx_number_2]->arg);
    4717           0 :         nb_cli_enqueue_change(vty, "./bfd/min-tx-interval", NB_OP_MODIFY,
    4718           0 :                               argv[idx_number_3]->arg);
    4719           0 :         nb_cli_enqueue_change(vty, "./bfd/detect_mult", NB_OP_MODIFY,
    4720           0 :                               argv[idx_number]->arg);
    4721             : 
    4722           0 :         return nb_cli_apply_changes(vty,
    4723             :                         FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
    4724             : }
    4725             : 
    4726             : #if HAVE_BFDD == 0
    4727             : ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
    4728             :       "no ip pim bfd (2-255) (1-65535) (1-65535)",
    4729             :       NO_STR
    4730             :       IP_STR
    4731             :       PIM_STR
    4732             :       "Enables BFD support\n"
    4733             :       "Detect Multiplier\n"
    4734             :       "Required min receive interval\n"
    4735             :       "Desired min transmit interval\n")
    4736             : #endif /* !HAVE_BFDD */
    4737             : 
    4738           0 : DEFPY(ip_msdp_peer, ip_msdp_peer_cmd,
    4739             :       "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
    4740             :       IP_STR
    4741             :       CFG_MSDP_STR
    4742             :       "Configure MSDP peer\n"
    4743             :       "Peer IP address\n"
    4744             :       "Source address for TCP connection\n"
    4745             :       "Local IP address\n")
    4746             : {
    4747           0 :         const char *vrfname;
    4748           0 :         char temp_xpath[XPATH_MAXLEN];
    4749           0 :         char msdp_peer_source_xpath[XPATH_MAXLEN];
    4750             : 
    4751           0 :         vrfname = pim_cli_get_vrf_name(vty);
    4752           0 :         if (vrfname == NULL)
    4753             :                 return CMD_WARNING_CONFIG_FAILED;
    4754             : 
    4755           0 :         snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
    4756             :                  FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
    4757             :                  "frr-routing:ipv4");
    4758           0 :         snprintf(temp_xpath, sizeof(temp_xpath),
    4759             :                  "/msdp-peer[peer-ip='%s']/source-ip", peer_str);
    4760           0 :         strlcat(msdp_peer_source_xpath, temp_xpath,
    4761             :                 sizeof(msdp_peer_source_xpath));
    4762             : 
    4763           0 :         nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
    4764             :                               source_str);
    4765             : 
    4766           0 :         return nb_cli_apply_changes(vty,
    4767             :                         FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
    4768             : }
    4769             : 
    4770           0 : DEFPY(ip_msdp_timers, ip_msdp_timers_cmd,
    4771             :       "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
    4772             :       IP_STR
    4773             :       CFG_MSDP_STR
    4774             :       "MSDP timers configuration\n"
    4775             :       "Keep alive period (in seconds)\n"
    4776             :       "Hold time period (in seconds)\n"
    4777             :       "Connection retry period (in seconds)\n")
    4778             : {
    4779           0 :         const char *vrfname;
    4780             : 
    4781           0 :         vrfname = pim_cli_get_vrf_name(vty);
    4782           0 :         if (vrfname == NULL)
    4783             :                 return CMD_WARNING_CONFIG_FAILED;
    4784             : 
    4785           0 :         nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str);
    4786           0 :         nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str);
    4787           0 :         if (connretry_str)
    4788           0 :                 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY,
    4789             :                                       connretry_str);
    4790             :         else
    4791           0 :                 nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY,
    4792             :                                       NULL);
    4793             : 
    4794           0 :         nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim",
    4795             :                              vrfname, "frr-routing:ipv4");
    4796           0 :         return CMD_SUCCESS;
    4797             : }
    4798             : 
    4799           0 : DEFPY(no_ip_msdp_timers, no_ip_msdp_timers_cmd,
    4800             :       "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]",
    4801             :       NO_STR
    4802             :       IP_STR
    4803             :       CFG_MSDP_STR
    4804             :       "MSDP timers configuration\n"
    4805             :       IGNORED_IN_NO_STR
    4806             :       IGNORED_IN_NO_STR
    4807             :       IGNORED_IN_NO_STR)
    4808             : {
    4809           0 :         const char *vrfname;
    4810             : 
    4811           0 :         vrfname = pim_cli_get_vrf_name(vty);
    4812           0 :         if (vrfname == NULL)
    4813             :                 return CMD_WARNING_CONFIG_FAILED;
    4814             : 
    4815           0 :         nb_cli_enqueue_change(vty, "./hold-time", NB_OP_DESTROY, NULL);
    4816           0 :         nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_DESTROY, NULL);
    4817           0 :         nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY, NULL);
    4818             : 
    4819           0 :         nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim",
    4820             :                              vrfname, "frr-routing:ipv4");
    4821             : 
    4822           0 :         return CMD_SUCCESS;
    4823             : }
    4824             : 
    4825           0 : DEFUN (no_ip_msdp_peer,
    4826             :        no_ip_msdp_peer_cmd,
    4827             :        "no ip msdp peer A.B.C.D",
    4828             :        NO_STR
    4829             :        IP_STR
    4830             :        CFG_MSDP_STR
    4831             :        "Delete MSDP peer\n"
    4832             :        "peer ip address\n")
    4833             : {
    4834           0 :         const char *vrfname;
    4835           0 :         char msdp_peer_xpath[XPATH_MAXLEN];
    4836           0 :         char temp_xpath[XPATH_MAXLEN];
    4837             : 
    4838           0 :         vrfname = pim_cli_get_vrf_name(vty);
    4839           0 :         if (vrfname == NULL)
    4840             :                 return CMD_WARNING_CONFIG_FAILED;
    4841             : 
    4842           0 :         snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath),
    4843             :                  FRR_PIM_VRF_XPATH,
    4844             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
    4845           0 :         snprintf(temp_xpath, sizeof(temp_xpath),
    4846             :                  "/msdp-peer[peer-ip='%s']",
    4847           0 :                  argv[4]->arg);
    4848             : 
    4849           0 :         strlcat(msdp_peer_xpath, temp_xpath, sizeof(msdp_peer_xpath));
    4850             : 
    4851           0 :         nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL);
    4852             : 
    4853           0 :         return nb_cli_apply_changes(vty, NULL);
    4854             : }
    4855             : 
    4856           0 : DEFPY(ip_msdp_mesh_group_member,
    4857             :       ip_msdp_mesh_group_member_cmd,
    4858             :       "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
    4859             :       IP_STR
    4860             :       CFG_MSDP_STR
    4861             :       "Configure MSDP mesh-group\n"
    4862             :       "Mesh group name\n"
    4863             :       "Mesh group member\n"
    4864             :       "Peer IP address\n")
    4865             : {
    4866           0 :         const char *vrfname;
    4867           0 :         char xpath_value[XPATH_MAXLEN];
    4868             : 
    4869           0 :         vrfname = pim_cli_get_vrf_name(vty);
    4870           0 :         if (vrfname == NULL)
    4871             :                 return CMD_WARNING_CONFIG_FAILED;
    4872             : 
    4873             :         /* Create mesh group. */
    4874           0 :         snprintf(xpath_value, sizeof(xpath_value),
    4875             :                  FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
    4876             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
    4877           0 :         nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
    4878             : 
    4879             :         /* Create mesh group member. */
    4880           0 :         strlcat(xpath_value, "/members[address='", sizeof(xpath_value));
    4881           0 :         strlcat(xpath_value, maddr_str, sizeof(xpath_value));
    4882           0 :         strlcat(xpath_value, "']", sizeof(xpath_value));
    4883           0 :         nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
    4884             : 
    4885           0 :         return nb_cli_apply_changes(vty, NULL);
    4886             : }
    4887             : 
    4888           0 : DEFPY(no_ip_msdp_mesh_group_member,
    4889             :       no_ip_msdp_mesh_group_member_cmd,
    4890             :       "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
    4891             :       NO_STR
    4892             :       IP_STR
    4893             :       CFG_MSDP_STR
    4894             :       "Delete MSDP mesh-group member\n"
    4895             :       "Mesh group name\n"
    4896             :       "Mesh group member\n"
    4897             :       "Peer IP address\n")
    4898             : {
    4899           0 :         const char *vrfname;
    4900           0 :         char xpath_value[XPATH_MAXLEN];
    4901           0 :         char xpath_member_value[XPATH_MAXLEN];
    4902             : 
    4903           0 :         vrfname = pim_cli_get_vrf_name(vty);
    4904           0 :         if (vrfname == NULL)
    4905             :                 return CMD_WARNING_CONFIG_FAILED;
    4906             : 
    4907             :         /* Get mesh group base XPath. */
    4908           0 :         snprintf(xpath_value, sizeof(xpath_value),
    4909             :                  FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
    4910             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
    4911             : 
    4912           0 :         if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) {
    4913           0 :                 vty_out(vty, "%% mesh-group does not exist\n");
    4914           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4915             :         }
    4916             : 
    4917             :         /* Remove mesh group member. */
    4918           0 :         strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
    4919           0 :         strlcat(xpath_member_value, "/members[address='",
    4920             :                 sizeof(xpath_member_value));
    4921           0 :         strlcat(xpath_member_value, maddr_str, sizeof(xpath_member_value));
    4922           0 :         strlcat(xpath_member_value, "']", sizeof(xpath_member_value));
    4923           0 :         if (!yang_dnode_exists(vty->candidate_config->dnode,
    4924             :                                xpath_member_value)) {
    4925           0 :                 vty_out(vty, "%% mesh-group member does not exist\n");
    4926           0 :                 return CMD_WARNING_CONFIG_FAILED;
    4927             :         }
    4928             : 
    4929           0 :         nb_cli_enqueue_change(vty, xpath_member_value, NB_OP_DESTROY, NULL);
    4930             : 
    4931             :         /*
    4932             :          * If this is the last member, then we must remove the group altogether
    4933             :          * to not break legacy CLI behaviour.
    4934             :          */
    4935           0 :         pim_cli_legacy_mesh_group_behavior(vty, gname);
    4936             : 
    4937           0 :         return nb_cli_apply_changes(vty, NULL);
    4938             : }
    4939             : 
    4940           0 : DEFPY(ip_msdp_mesh_group_source,
    4941             :       ip_msdp_mesh_group_source_cmd,
    4942             :       "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
    4943             :       IP_STR
    4944             :       CFG_MSDP_STR
    4945             :       "Configure MSDP mesh-group\n"
    4946             :       "Mesh group name\n"
    4947             :       "Mesh group local address\n"
    4948             :       "Source IP address for the TCP connection\n")
    4949             : {
    4950           0 :         const char *vrfname;
    4951           0 :         char xpath_value[XPATH_MAXLEN];
    4952             : 
    4953           0 :         vrfname = pim_cli_get_vrf_name(vty);
    4954           0 :         if (vrfname == NULL)
    4955             :                 return CMD_WARNING_CONFIG_FAILED;
    4956             : 
    4957             :         /* Create mesh group. */
    4958           0 :         snprintf(xpath_value, sizeof(xpath_value),
    4959             :                  FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
    4960             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
    4961           0 :         nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
    4962             : 
    4963             :         /* Create mesh group source. */
    4964           0 :         strlcat(xpath_value, "/source", sizeof(xpath_value));
    4965           0 :         nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str);
    4966             : 
    4967           0 :         return nb_cli_apply_changes(vty, NULL);
    4968             : }
    4969             : 
    4970           0 : DEFPY(no_ip_msdp_mesh_group_source,
    4971             :       no_ip_msdp_mesh_group_source_cmd,
    4972             :       "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
    4973             :       NO_STR
    4974             :       IP_STR
    4975             :       CFG_MSDP_STR
    4976             :       "Delete MSDP mesh-group source\n"
    4977             :       "Mesh group name\n"
    4978             :       "Mesh group source\n"
    4979             :       "Mesh group local address\n")
    4980             : {
    4981           0 :         const char *vrfname;
    4982           0 :         char xpath_value[XPATH_MAXLEN];
    4983             : 
    4984           0 :         vrfname = pim_cli_get_vrf_name(vty);
    4985           0 :         if (vrfname == NULL)
    4986             :                 return CMD_WARNING_CONFIG_FAILED;
    4987             : 
    4988             :         /* Get mesh group base XPath. */
    4989           0 :         snprintf(xpath_value, sizeof(xpath_value),
    4990             :                  FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
    4991             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
    4992           0 :         nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
    4993             : 
    4994             :         /* Create mesh group source. */
    4995           0 :         strlcat(xpath_value, "/source", sizeof(xpath_value));
    4996           0 :         nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
    4997             : 
    4998             :         /*
    4999             :          * If this is the last member, then we must remove the group altogether
    5000             :          * to not break legacy CLI behaviour.
    5001             :          */
    5002           0 :         pim_cli_legacy_mesh_group_behavior(vty, gname);
    5003             : 
    5004           0 :         return nb_cli_apply_changes(vty, NULL);
    5005             : }
    5006             : 
    5007           0 : DEFPY(no_ip_msdp_mesh_group,
    5008             :       no_ip_msdp_mesh_group_cmd,
    5009             :       "no ip msdp mesh-group WORD$gname",
    5010             :       NO_STR
    5011             :       IP_STR
    5012             :       CFG_MSDP_STR
    5013             :       "Delete MSDP mesh-group\n"
    5014             :       "Mesh group name\n")
    5015             : {
    5016           0 :         const char *vrfname;
    5017           0 :         char xpath_value[XPATH_MAXLEN];
    5018             : 
    5019           0 :         vrfname = pim_cli_get_vrf_name(vty);
    5020           0 :         if (vrfname == NULL)
    5021             :                 return CMD_WARNING_CONFIG_FAILED;
    5022             : 
    5023             :         /* Get mesh group base XPath. */
    5024           0 :         snprintf(xpath_value, sizeof(xpath_value),
    5025             :                  FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']",
    5026             :                  "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
    5027           0 :         if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
    5028             :                 return CMD_SUCCESS;
    5029             : 
    5030           0 :         nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
    5031           0 :         return nb_cli_apply_changes(vty, NULL);
    5032             : }
    5033             : 
    5034           0 : static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg,
    5035             :                                     struct json_object *json)
    5036             : {
    5037           0 :         struct listnode *mbrnode;
    5038           0 :         struct pim_msdp_mg_mbr *mbr;
    5039           0 :         char mbr_str[INET_ADDRSTRLEN];
    5040           0 :         char src_str[INET_ADDRSTRLEN];
    5041           0 :         char state_str[PIM_MSDP_STATE_STRLEN];
    5042           0 :         enum pim_msdp_peer_state state;
    5043           0 :         json_object *json_mg_row = NULL;
    5044           0 :         json_object *json_members = NULL;
    5045           0 :         json_object *json_row = NULL;
    5046             : 
    5047           0 :         pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
    5048           0 :         if (json) {
    5049             :                 /* currently there is only one mesh group but we should still
    5050             :                  * make
    5051             :                  * it a dict with mg-name as key */
    5052           0 :                 json_mg_row = json_object_new_object();
    5053           0 :                 json_object_string_add(json_mg_row, "name",
    5054           0 :                                        mg->mesh_group_name);
    5055           0 :                 json_object_string_add(json_mg_row, "source", src_str);
    5056             :         } else {
    5057           0 :                 vty_out(vty, "Mesh group : %s\n", mg->mesh_group_name);
    5058           0 :                 vty_out(vty, "  Source : %s\n", src_str);
    5059           0 :                 vty_out(vty, "  Member                 State\n");
    5060             :         }
    5061             : 
    5062           0 :         for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
    5063           0 :                 pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str, sizeof(mbr_str));
    5064           0 :                 if (mbr->mp) {
    5065           0 :                         state = mbr->mp->state;
    5066             :                 } else {
    5067             :                         state = PIM_MSDP_DISABLED;
    5068             :                 }
    5069           0 :                 pim_msdp_state_dump(state, state_str, sizeof(state_str));
    5070           0 :                 if (json) {
    5071           0 :                         json_row = json_object_new_object();
    5072           0 :                         json_object_string_add(json_row, "member", mbr_str);
    5073           0 :                         json_object_string_add(json_row, "state", state_str);
    5074           0 :                         if (!json_members) {
    5075           0 :                                 json_members = json_object_new_object();
    5076           0 :                                 json_object_object_add(json_mg_row, "members",
    5077             :                                                        json_members);
    5078             :                         }
    5079           0 :                         json_object_object_add(json_members, mbr_str, json_row);
    5080             :                 } else {
    5081           0 :                         vty_out(vty, "  %-15s  %11s\n", mbr_str, state_str);
    5082             :                 }
    5083             :         }
    5084             : 
    5085           0 :         if (json)
    5086           0 :                 json_object_object_add(json, mg->mesh_group_name, json_mg_row);
    5087           0 : }
    5088             : 
    5089           0 : DEFUN (show_ip_msdp_mesh_group,
    5090             :        show_ip_msdp_mesh_group_cmd,
    5091             :        "show ip msdp [vrf NAME] mesh-group [json]",
    5092             :        SHOW_STR
    5093             :        IP_STR
    5094             :        MSDP_STR
    5095             :        VRF_CMD_HELP_STR
    5096             :        "MSDP mesh-group information\n"
    5097             :        JSON_STR)
    5098             : {
    5099           0 :         bool uj = use_json(argc, argv);
    5100           0 :         int idx = 2;
    5101           0 :         struct pim_msdp_mg *mg;
    5102           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    5103           0 :         struct pim_instance *pim;
    5104           0 :         struct json_object *json = NULL;
    5105             : 
    5106           0 :         if (!vrf)
    5107             :                 return CMD_WARNING;
    5108             : 
    5109           0 :         pim = vrf->info;
    5110             :         /* Quick case: list is empty. */
    5111           0 :         if (SLIST_EMPTY(&pim->msdp.mglist)) {
    5112           0 :                 if (uj)
    5113           0 :                         vty_out(vty, "{}\n");
    5114             : 
    5115           0 :                 return CMD_SUCCESS;
    5116             :         }
    5117             : 
    5118           0 :         if (uj)
    5119           0 :                 json = json_object_new_object();
    5120             : 
    5121           0 :         SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
    5122           0 :                 ip_msdp_show_mesh_group(vty, mg, json);
    5123             : 
    5124           0 :         if (uj)
    5125           0 :                 vty_json(vty, json);
    5126             : 
    5127             :         return CMD_SUCCESS;
    5128             : }
    5129             : 
    5130           0 : DEFUN (show_ip_msdp_mesh_group_vrf_all,
    5131             :        show_ip_msdp_mesh_group_vrf_all_cmd,
    5132             :        "show ip msdp vrf all mesh-group [json]",
    5133             :        SHOW_STR
    5134             :        IP_STR
    5135             :        MSDP_STR
    5136             :        VRF_CMD_HELP_STR
    5137             :        "MSDP mesh-group information\n"
    5138             :        JSON_STR)
    5139             : {
    5140           0 :         bool uj = use_json(argc, argv);
    5141           0 :         struct json_object *json = NULL, *vrf_json = NULL;
    5142           0 :         struct pim_instance *pim;
    5143           0 :         struct pim_msdp_mg *mg;
    5144           0 :         struct vrf *vrf;
    5145             : 
    5146           0 :         if (uj)
    5147           0 :                 json = json_object_new_object();
    5148             : 
    5149           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    5150           0 :                 if (uj) {
    5151           0 :                         vrf_json = json_object_new_object();
    5152           0 :                         json_object_object_add(json, vrf->name, vrf_json);
    5153             :                 } else
    5154           0 :                         vty_out(vty, "VRF: %s\n", vrf->name);
    5155             : 
    5156           0 :                 pim = vrf->info;
    5157           0 :                 SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
    5158           0 :                         ip_msdp_show_mesh_group(vty, mg, vrf_json);
    5159             :         }
    5160             : 
    5161           0 :         if (uj)
    5162           0 :                 vty_json(vty, json);
    5163             : 
    5164             : 
    5165           0 :         return CMD_SUCCESS;
    5166             : }
    5167             : 
    5168           0 : static void ip_msdp_show_peers(struct pim_instance *pim, struct vty *vty,
    5169             :                                bool uj)
    5170             : {
    5171           0 :         struct listnode *mpnode;
    5172           0 :         struct pim_msdp_peer *mp;
    5173           0 :         char peer_str[INET_ADDRSTRLEN];
    5174           0 :         char local_str[INET_ADDRSTRLEN];
    5175           0 :         char state_str[PIM_MSDP_STATE_STRLEN];
    5176           0 :         char timebuf[PIM_MSDP_UPTIME_STRLEN];
    5177           0 :         int64_t now;
    5178           0 :         json_object *json = NULL;
    5179           0 :         json_object *json_row = NULL;
    5180             : 
    5181             : 
    5182           0 :         if (uj) {
    5183           0 :                 json = json_object_new_object();
    5184             :         } else {
    5185           0 :                 vty_out(vty,
    5186             :                         "Peer                       Local        State    Uptime   SaCnt\n");
    5187             :         }
    5188             : 
    5189           0 :         for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
    5190           0 :                 if (mp->state == PIM_MSDP_ESTABLISHED) {
    5191           0 :                         now = pim_time_monotonic_sec();
    5192           0 :                         pim_time_uptime(timebuf, sizeof(timebuf),
    5193           0 :                                         now - mp->uptime);
    5194             :                 } else {
    5195           0 :                         strlcpy(timebuf, "-", sizeof(timebuf));
    5196             :                 }
    5197           0 :                 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
    5198           0 :                 pim_inet4_dump("<local?>", mp->local, local_str,
    5199             :                                sizeof(local_str));
    5200           0 :                 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
    5201           0 :                 if (uj) {
    5202           0 :                         json_row = json_object_new_object();
    5203           0 :                         json_object_string_add(json_row, "peer", peer_str);
    5204           0 :                         json_object_string_add(json_row, "local", local_str);
    5205           0 :                         json_object_string_add(json_row, "state", state_str);
    5206           0 :                         json_object_string_add(json_row, "upTime", timebuf);
    5207           0 :                         json_object_int_add(json_row, "saCount", mp->sa_cnt);
    5208           0 :                         json_object_object_add(json, peer_str, json_row);
    5209             :                 } else {
    5210           0 :                         vty_out(vty, "%-15s  %15s  %11s  %8s  %6d\n", peer_str,
    5211             :                                 local_str, state_str, timebuf, mp->sa_cnt);
    5212             :                 }
    5213             :         }
    5214             : 
    5215           0 :         if (uj)
    5216           0 :                 vty_json(vty, json);
    5217           0 : }
    5218             : 
    5219           0 : static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
    5220             :                                       const char *peer, bool uj)
    5221             : {
    5222           0 :         struct listnode *mpnode;
    5223           0 :         struct pim_msdp_peer *mp;
    5224           0 :         char peer_str[INET_ADDRSTRLEN];
    5225           0 :         char local_str[INET_ADDRSTRLEN];
    5226           0 :         char state_str[PIM_MSDP_STATE_STRLEN];
    5227           0 :         char timebuf[PIM_MSDP_UPTIME_STRLEN];
    5228           0 :         char katimer[PIM_MSDP_TIMER_STRLEN];
    5229           0 :         char crtimer[PIM_MSDP_TIMER_STRLEN];
    5230           0 :         char holdtimer[PIM_MSDP_TIMER_STRLEN];
    5231           0 :         int64_t now;
    5232           0 :         json_object *json = NULL;
    5233           0 :         json_object *json_row = NULL;
    5234             : 
    5235           0 :         if (uj) {
    5236           0 :                 json = json_object_new_object();
    5237             :         }
    5238             : 
    5239           0 :         for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) {
    5240           0 :                 pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
    5241           0 :                 if (strcmp(peer, "detail") && strcmp(peer, peer_str))
    5242           0 :                         continue;
    5243             : 
    5244           0 :                 if (mp->state == PIM_MSDP_ESTABLISHED) {
    5245           0 :                         now = pim_time_monotonic_sec();
    5246           0 :                         pim_time_uptime(timebuf, sizeof(timebuf),
    5247           0 :                                         now - mp->uptime);
    5248             :                 } else {
    5249           0 :                         strlcpy(timebuf, "-", sizeof(timebuf));
    5250             :                 }
    5251           0 :                 pim_inet4_dump("<local?>", mp->local, local_str,
    5252             :                                sizeof(local_str));
    5253           0 :                 pim_msdp_state_dump(mp->state, state_str, sizeof(state_str));
    5254           0 :                 pim_time_timer_to_hhmmss(katimer, sizeof(katimer),
    5255             :                                          mp->ka_timer);
    5256           0 :                 pim_time_timer_to_hhmmss(crtimer, sizeof(crtimer),
    5257             :                                          mp->cr_timer);
    5258           0 :                 pim_time_timer_to_hhmmss(holdtimer, sizeof(holdtimer),
    5259             :                                          mp->hold_timer);
    5260             : 
    5261           0 :                 if (uj) {
    5262           0 :                         json_row = json_object_new_object();
    5263           0 :                         json_object_string_add(json_row, "peer", peer_str);
    5264           0 :                         json_object_string_add(json_row, "local", local_str);
    5265           0 :                         if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
    5266           0 :                                 json_object_string_add(json_row,
    5267             :                                                        "meshGroupName",
    5268           0 :                                                        mp->mesh_group_name);
    5269           0 :                         json_object_string_add(json_row, "state", state_str);
    5270           0 :                         json_object_string_add(json_row, "upTime", timebuf);
    5271           0 :                         json_object_string_add(json_row, "keepAliveTimer",
    5272             :                                                katimer);
    5273           0 :                         json_object_string_add(json_row, "connRetryTimer",
    5274             :                                                crtimer);
    5275           0 :                         json_object_string_add(json_row, "holdTimer",
    5276             :                                                holdtimer);
    5277           0 :                         json_object_string_add(json_row, "lastReset",
    5278           0 :                                                mp->last_reset);
    5279           0 :                         json_object_int_add(json_row, "connAttempts",
    5280           0 :                                             mp->conn_attempts);
    5281           0 :                         json_object_int_add(json_row, "establishedChanges",
    5282           0 :                                             mp->est_flaps);
    5283           0 :                         json_object_int_add(json_row, "saCount", mp->sa_cnt);
    5284           0 :                         json_object_int_add(json_row, "kaSent", mp->ka_tx_cnt);
    5285           0 :                         json_object_int_add(json_row, "kaRcvd", mp->ka_rx_cnt);
    5286           0 :                         json_object_int_add(json_row, "saSent", mp->sa_tx_cnt);
    5287           0 :                         json_object_int_add(json_row, "saRcvd", mp->sa_rx_cnt);
    5288           0 :                         json_object_object_add(json, peer_str, json_row);
    5289             :                 } else {
    5290           0 :                         vty_out(vty, "Peer : %s\n", peer_str);
    5291           0 :                         vty_out(vty, "  Local               : %s\n", local_str);
    5292           0 :                         if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
    5293           0 :                                 vty_out(vty, "  Mesh Group          : %s\n",
    5294             :                                         mp->mesh_group_name);
    5295           0 :                         vty_out(vty, "  State               : %s\n", state_str);
    5296           0 :                         vty_out(vty, "  Uptime              : %s\n", timebuf);
    5297             : 
    5298           0 :                         vty_out(vty, "  Keepalive Timer     : %s\n", katimer);
    5299           0 :                         vty_out(vty, "  Conn Retry Timer    : %s\n", crtimer);
    5300           0 :                         vty_out(vty, "  Hold Timer          : %s\n", holdtimer);
    5301           0 :                         vty_out(vty, "  Last Reset          : %s\n",
    5302           0 :                                 mp->last_reset);
    5303           0 :                         vty_out(vty, "  Conn Attempts       : %d\n",
    5304             :                                 mp->conn_attempts);
    5305           0 :                         vty_out(vty, "  Established Changes : %d\n",
    5306             :                                 mp->est_flaps);
    5307           0 :                         vty_out(vty, "  SA Count            : %d\n",
    5308             :                                 mp->sa_cnt);
    5309           0 :                         vty_out(vty, "  Statistics          :\n");
    5310           0 :                         vty_out(vty,
    5311             :                                 "                       Sent       Rcvd\n");
    5312           0 :                         vty_out(vty, "    Keepalives : %10d %10d\n",
    5313             :                                 mp->ka_tx_cnt, mp->ka_rx_cnt);
    5314           0 :                         vty_out(vty, "    SAs        : %10d %10d\n",
    5315             :                                 mp->sa_tx_cnt, mp->sa_rx_cnt);
    5316           0 :                         vty_out(vty, "\n");
    5317             :                 }
    5318             :         }
    5319             : 
    5320           0 :         if (uj)
    5321           0 :                 vty_json(vty, json);
    5322           0 : }
    5323             : 
    5324           0 : DEFUN (show_ip_msdp_peer_detail,
    5325             :        show_ip_msdp_peer_detail_cmd,
    5326             :        "show ip msdp [vrf NAME] peer [detail|A.B.C.D] [json]",
    5327             :        SHOW_STR
    5328             :        IP_STR
    5329             :        MSDP_STR
    5330             :        VRF_CMD_HELP_STR
    5331             :        "MSDP peer information\n"
    5332             :        "Detailed output\n"
    5333             :        "peer ip address\n"
    5334             :        JSON_STR)
    5335             : {
    5336           0 :         bool uj = use_json(argc, argv);
    5337           0 :         int idx = 2;
    5338           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    5339             : 
    5340           0 :         if (!vrf)
    5341             :                 return CMD_WARNING;
    5342             : 
    5343           0 :         char *arg = NULL;
    5344             : 
    5345           0 :         if (argv_find(argv, argc, "detail", &idx))
    5346           0 :                 arg = argv[idx]->text;
    5347           0 :         else if (argv_find(argv, argc, "A.B.C.D", &idx))
    5348           0 :                 arg = argv[idx]->arg;
    5349             : 
    5350           0 :         if (arg)
    5351           0 :                 ip_msdp_show_peers_detail(vrf->info, vty, argv[idx]->arg, uj);
    5352             :         else
    5353           0 :                 ip_msdp_show_peers(vrf->info, vty, uj);
    5354             : 
    5355             :         return CMD_SUCCESS;
    5356             : }
    5357             : 
    5358           0 : DEFUN (show_ip_msdp_peer_detail_vrf_all,
    5359             :        show_ip_msdp_peer_detail_vrf_all_cmd,
    5360             :        "show ip msdp vrf all peer [detail|A.B.C.D] [json]",
    5361             :        SHOW_STR
    5362             :        IP_STR
    5363             :        MSDP_STR
    5364             :        VRF_CMD_HELP_STR
    5365             :        "MSDP peer information\n"
    5366             :        "Detailed output\n"
    5367             :        "peer ip address\n"
    5368             :        JSON_STR)
    5369             : {
    5370           0 :         int idx = 2;
    5371           0 :         bool uj = use_json(argc, argv);
    5372           0 :         struct vrf *vrf;
    5373           0 :         bool first = true;
    5374             : 
    5375           0 :         if (uj)
    5376           0 :                 vty_out(vty, "{ ");
    5377           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    5378           0 :                 if (uj) {
    5379           0 :                         if (!first)
    5380           0 :                                 vty_out(vty, ", ");
    5381           0 :                         vty_out(vty, " \"%s\": ", vrf->name);
    5382           0 :                         first = false;
    5383             :                 } else
    5384           0 :                         vty_out(vty, "VRF: %s\n", vrf->name);
    5385           0 :                 if (argv_find(argv, argc, "detail", &idx)
    5386           0 :                     || argv_find(argv, argc, "A.B.C.D", &idx))
    5387           0 :                         ip_msdp_show_peers_detail(vrf->info, vty,
    5388           0 :                                                   argv[idx]->arg, uj);
    5389             :                 else
    5390           0 :                         ip_msdp_show_peers(vrf->info, vty, uj);
    5391             :         }
    5392           0 :         if (uj)
    5393           0 :                 vty_out(vty, "}\n");
    5394             : 
    5395           0 :         return CMD_SUCCESS;
    5396             : }
    5397             : 
    5398           0 : static void ip_msdp_show_sa(struct pim_instance *pim, struct vty *vty, bool uj)
    5399             : {
    5400           0 :         struct listnode *sanode;
    5401           0 :         struct pim_msdp_sa *sa;
    5402           0 :         char rp_str[INET_ADDRSTRLEN];
    5403           0 :         char timebuf[PIM_MSDP_UPTIME_STRLEN];
    5404           0 :         char spt_str[8];
    5405           0 :         char local_str[8];
    5406           0 :         int64_t now;
    5407           0 :         json_object *json = NULL;
    5408           0 :         json_object *json_group = NULL;
    5409           0 :         json_object *json_row = NULL;
    5410             : 
    5411           0 :         if (uj) {
    5412           0 :                 json = json_object_new_object();
    5413             :         } else {
    5414           0 :                 vty_out(vty,
    5415             :                         "Source                     Group               RP  Local  SPT    Uptime\n");
    5416             :         }
    5417             : 
    5418           0 :         for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
    5419           0 :                 now = pim_time_monotonic_sec();
    5420           0 :                 pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
    5421           0 :                 if (sa->flags & PIM_MSDP_SAF_PEER) {
    5422           0 :                         pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
    5423           0 :                         if (sa->up) {
    5424           0 :                                 strlcpy(spt_str, "yes", sizeof(spt_str));
    5425             :                         } else {
    5426           0 :                                 strlcpy(spt_str, "no", sizeof(spt_str));
    5427             :                         }
    5428             :                 } else {
    5429           0 :                         strlcpy(rp_str, "-", sizeof(rp_str));
    5430           0 :                         strlcpy(spt_str, "-", sizeof(spt_str));
    5431             :                 }
    5432           0 :                 if (sa->flags & PIM_MSDP_SAF_LOCAL) {
    5433           0 :                         strlcpy(local_str, "yes", sizeof(local_str));
    5434             :                 } else {
    5435           0 :                         strlcpy(local_str, "no", sizeof(local_str));
    5436             :                 }
    5437           0 :                 if (uj) {
    5438           0 :                         char src_str[PIM_ADDRSTRLEN];
    5439           0 :                         char grp_str[PIM_ADDRSTRLEN];
    5440             : 
    5441           0 :                         snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
    5442             :                                    &sa->sg.grp);
    5443           0 :                         snprintfrr(src_str, sizeof(src_str), "%pPAs",
    5444             :                                    &sa->sg.src);
    5445             : 
    5446           0 :                         json_object_object_get_ex(json, grp_str, &json_group);
    5447             : 
    5448           0 :                         if (!json_group) {
    5449           0 :                                 json_group = json_object_new_object();
    5450           0 :                                 json_object_object_add(json, grp_str,
    5451             :                                                        json_group);
    5452             :                         }
    5453             : 
    5454           0 :                         json_row = json_object_new_object();
    5455           0 :                         json_object_string_add(json_row, "source", src_str);
    5456           0 :                         json_object_string_add(json_row, "group", grp_str);
    5457           0 :                         json_object_string_add(json_row, "rp", rp_str);
    5458           0 :                         json_object_string_add(json_row, "local", local_str);
    5459           0 :                         json_object_string_add(json_row, "sptSetup", spt_str);
    5460           0 :                         json_object_string_add(json_row, "upTime", timebuf);
    5461           0 :                         json_object_object_add(json_group, src_str, json_row);
    5462             :                 } else {
    5463           0 :                         vty_out(vty, "%-15pPAs  %15pPAs  %15s  %5c  %3c  %8s\n",
    5464           0 :                                 &sa->sg.src, &sa->sg.grp, rp_str, local_str[0],
    5465           0 :                                 spt_str[0], timebuf);
    5466             :                 }
    5467             :         }
    5468             : 
    5469           0 :         if (uj)
    5470           0 :                 vty_json(vty, json);
    5471           0 : }
    5472             : 
    5473           0 : static void ip_msdp_show_sa_entry_detail(struct pim_msdp_sa *sa,
    5474             :                                          const char *src_str,
    5475             :                                          const char *grp_str, struct vty *vty,
    5476             :                                          bool uj, json_object *json)
    5477             : {
    5478           0 :         char rp_str[INET_ADDRSTRLEN];
    5479           0 :         char peer_str[INET_ADDRSTRLEN];
    5480           0 :         char timebuf[PIM_MSDP_UPTIME_STRLEN];
    5481           0 :         char spt_str[8];
    5482           0 :         char local_str[8];
    5483           0 :         char statetimer[PIM_MSDP_TIMER_STRLEN];
    5484           0 :         int64_t now;
    5485           0 :         json_object *json_group = NULL;
    5486           0 :         json_object *json_row = NULL;
    5487             : 
    5488           0 :         now = pim_time_monotonic_sec();
    5489           0 :         pim_time_uptime(timebuf, sizeof(timebuf), now - sa->uptime);
    5490           0 :         if (sa->flags & PIM_MSDP_SAF_PEER) {
    5491           0 :                 pim_inet4_dump("<rp?>", sa->rp, rp_str, sizeof(rp_str));
    5492           0 :                 pim_inet4_dump("<peer?>", sa->peer, peer_str, sizeof(peer_str));
    5493           0 :                 if (sa->up) {
    5494           0 :                         strlcpy(spt_str, "yes", sizeof(spt_str));
    5495             :                 } else {
    5496           0 :                         strlcpy(spt_str, "no", sizeof(spt_str));
    5497             :                 }
    5498             :         } else {
    5499           0 :                 strlcpy(rp_str, "-", sizeof(rp_str));
    5500           0 :                 strlcpy(peer_str, "-", sizeof(peer_str));
    5501           0 :                 strlcpy(spt_str, "-", sizeof(spt_str));
    5502             :         }
    5503           0 :         if (sa->flags & PIM_MSDP_SAF_LOCAL) {
    5504           0 :                 strlcpy(local_str, "yes", sizeof(local_str));
    5505             :         } else {
    5506           0 :                 strlcpy(local_str, "no", sizeof(local_str));
    5507             :         }
    5508           0 :         pim_time_timer_to_hhmmss(statetimer, sizeof(statetimer),
    5509             :                                  sa->sa_state_timer);
    5510           0 :         if (uj) {
    5511           0 :                 json_object_object_get_ex(json, grp_str, &json_group);
    5512             : 
    5513           0 :                 if (!json_group) {
    5514           0 :                         json_group = json_object_new_object();
    5515           0 :                         json_object_object_add(json, grp_str, json_group);
    5516             :                 }
    5517             : 
    5518           0 :                 json_row = json_object_new_object();
    5519           0 :                 json_object_string_add(json_row, "source", src_str);
    5520           0 :                 json_object_string_add(json_row, "group", grp_str);
    5521           0 :                 json_object_string_add(json_row, "rp", rp_str);
    5522           0 :                 json_object_string_add(json_row, "local", local_str);
    5523           0 :                 json_object_string_add(json_row, "sptSetup", spt_str);
    5524           0 :                 json_object_string_add(json_row, "upTime", timebuf);
    5525           0 :                 json_object_string_add(json_row, "stateTimer", statetimer);
    5526           0 :                 json_object_object_add(json_group, src_str, json_row);
    5527             :         } else {
    5528           0 :                 vty_out(vty, "SA : %s\n", sa->sg_str);
    5529           0 :                 vty_out(vty, "  RP          : %s\n", rp_str);
    5530           0 :                 vty_out(vty, "  Peer        : %s\n", peer_str);
    5531           0 :                 vty_out(vty, "  Local       : %s\n", local_str);
    5532           0 :                 vty_out(vty, "  SPT Setup   : %s\n", spt_str);
    5533           0 :                 vty_out(vty, "  Uptime      : %s\n", timebuf);
    5534           0 :                 vty_out(vty, "  State Timer : %s\n", statetimer);
    5535           0 :                 vty_out(vty, "\n");
    5536             :         }
    5537           0 : }
    5538             : 
    5539           0 : static void ip_msdp_show_sa_detail(struct pim_instance *pim, struct vty *vty,
    5540             :                                    bool uj)
    5541             : {
    5542           0 :         struct listnode *sanode;
    5543           0 :         struct pim_msdp_sa *sa;
    5544           0 :         json_object *json = NULL;
    5545             : 
    5546           0 :         if (uj) {
    5547           0 :                 json = json_object_new_object();
    5548             :         }
    5549             : 
    5550           0 :         for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
    5551           0 :                 char src_str[PIM_ADDRSTRLEN];
    5552           0 :                 char grp_str[PIM_ADDRSTRLEN];
    5553             : 
    5554           0 :                 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
    5555           0 :                 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
    5556             : 
    5557           0 :                 ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty, uj,
    5558             :                                              json);
    5559             :         }
    5560             : 
    5561           0 :         if (uj)
    5562           0 :                 vty_json(vty, json);
    5563           0 : }
    5564             : 
    5565           0 : DEFUN (show_ip_msdp_sa_detail,
    5566             :        show_ip_msdp_sa_detail_cmd,
    5567             :        "show ip msdp [vrf NAME] sa detail [json]",
    5568             :        SHOW_STR
    5569             :        IP_STR
    5570             :        MSDP_STR
    5571             :        VRF_CMD_HELP_STR
    5572             :        "MSDP active-source information\n"
    5573             :        "Detailed output\n"
    5574             :        JSON_STR)
    5575             : {
    5576           0 :         bool uj = use_json(argc, argv);
    5577           0 :         int idx = 2;
    5578           0 :         struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    5579             : 
    5580           0 :         if (!vrf)
    5581             :                 return CMD_WARNING;
    5582             : 
    5583           0 :         ip_msdp_show_sa_detail(vrf->info, vty, uj);
    5584             : 
    5585           0 :         return CMD_SUCCESS;
    5586             : }
    5587             : 
    5588           0 : DEFUN (show_ip_msdp_sa_detail_vrf_all,
    5589             :        show_ip_msdp_sa_detail_vrf_all_cmd,
    5590             :        "show ip msdp vrf all sa detail [json]",
    5591             :        SHOW_STR
    5592             :        IP_STR
    5593             :        MSDP_STR
    5594             :        VRF_CMD_HELP_STR
    5595             :        "MSDP active-source information\n"
    5596             :        "Detailed output\n"
    5597             :        JSON_STR)
    5598             : {
    5599           0 :         bool uj = use_json(argc, argv);
    5600           0 :         struct vrf *vrf;
    5601           0 :         bool first = true;
    5602             : 
    5603           0 :         if (uj)
    5604           0 :                 vty_out(vty, "{ ");
    5605           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    5606           0 :                 if (uj) {
    5607           0 :                         if (!first)
    5608           0 :                                 vty_out(vty, ", ");
    5609           0 :                         vty_out(vty, " \"%s\": ", vrf->name);
    5610           0 :                         first = false;
    5611             :                 } else
    5612           0 :                         vty_out(vty, "VRF: %s\n", vrf->name);
    5613           0 :                 ip_msdp_show_sa_detail(vrf->info, vty, uj);
    5614             :         }
    5615           0 :         if (uj)
    5616           0 :                 vty_out(vty, "}\n");
    5617             : 
    5618           0 :         return CMD_SUCCESS;
    5619             : }
    5620             : 
    5621           0 : static void ip_msdp_show_sa_addr(struct pim_instance *pim, struct vty *vty,
    5622             :                                  const char *addr, bool uj)
    5623             : {
    5624           0 :         struct listnode *sanode;
    5625           0 :         struct pim_msdp_sa *sa;
    5626           0 :         json_object *json = NULL;
    5627             : 
    5628           0 :         if (uj) {
    5629           0 :                 json = json_object_new_object();
    5630             :         }
    5631             : 
    5632           0 :         for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
    5633           0 :                 char src_str[PIM_ADDRSTRLEN];
    5634           0 :                 char grp_str[PIM_ADDRSTRLEN];
    5635             : 
    5636           0 :                 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
    5637           0 :                 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
    5638             : 
    5639           0 :                 if (!strcmp(addr, src_str) || !strcmp(addr, grp_str)) {
    5640           0 :                         ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
    5641             :                                                      uj, json);
    5642             :                 }
    5643             :         }
    5644             : 
    5645           0 :         if (uj)
    5646           0 :                 vty_json(vty, json);
    5647           0 : }
    5648             : 
    5649           0 : static void ip_msdp_show_sa_sg(struct pim_instance *pim, struct vty *vty,
    5650             :                                const char *src, const char *grp, bool uj)
    5651             : {
    5652           0 :         struct listnode *sanode;
    5653           0 :         struct pim_msdp_sa *sa;
    5654           0 :         json_object *json = NULL;
    5655             : 
    5656           0 :         if (uj) {
    5657           0 :                 json = json_object_new_object();
    5658             :         }
    5659             : 
    5660           0 :         for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
    5661           0 :                 char src_str[PIM_ADDRSTRLEN];
    5662           0 :                 char grp_str[PIM_ADDRSTRLEN];
    5663             : 
    5664           0 :                 snprintfrr(grp_str, sizeof(grp_str), "%pPAs", &sa->sg.grp);
    5665           0 :                 snprintfrr(src_str, sizeof(src_str), "%pPAs", &sa->sg.src);
    5666             : 
    5667           0 :                 if (!strcmp(src, src_str) && !strcmp(grp, grp_str)) {
    5668           0 :                         ip_msdp_show_sa_entry_detail(sa, src_str, grp_str, vty,
    5669             :                                                      uj, json);
    5670             :                 }
    5671             :         }
    5672             : 
    5673           0 :         if (uj)
    5674           0 :                 vty_json(vty, json);
    5675           0 : }
    5676             : 
    5677           0 : DEFUN (show_ip_msdp_sa_sg,
    5678             :        show_ip_msdp_sa_sg_cmd,
    5679             :        "show ip msdp [vrf NAME] sa [A.B.C.D [A.B.C.D]] [json]",
    5680             :        SHOW_STR
    5681             :        IP_STR
    5682             :        MSDP_STR
    5683             :        VRF_CMD_HELP_STR
    5684             :        "MSDP active-source information\n"
    5685             :        "source or group ip\n"
    5686             :        "group ip\n"
    5687             :        JSON_STR)
    5688             : {
    5689           0 :         bool uj = use_json(argc, argv);
    5690           0 :         struct vrf *vrf;
    5691           0 :         int idx = 2;
    5692             : 
    5693           0 :         vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    5694             : 
    5695           0 :         if (!vrf)
    5696             :                 return CMD_WARNING;
    5697             : 
    5698           0 :         char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
    5699           0 :                 : NULL;
    5700           0 :         char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
    5701           0 :                 ? argv[idx]->arg
    5702           0 :                 : NULL;
    5703             : 
    5704           0 :         if (src_ip && grp_ip)
    5705           0 :                 ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
    5706           0 :         else if (src_ip)
    5707           0 :                 ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
    5708             :         else
    5709           0 :                 ip_msdp_show_sa(vrf->info, vty, uj);
    5710             : 
    5711             :         return CMD_SUCCESS;
    5712             : }
    5713             : 
    5714           0 : DEFUN (show_ip_msdp_sa_sg_vrf_all,
    5715             :        show_ip_msdp_sa_sg_vrf_all_cmd,
    5716             :        "show ip msdp vrf all sa [A.B.C.D [A.B.C.D]] [json]",
    5717             :        SHOW_STR
    5718             :        IP_STR
    5719             :        MSDP_STR
    5720             :        VRF_CMD_HELP_STR
    5721             :        "MSDP active-source information\n"
    5722             :        "source or group ip\n"
    5723             :        "group ip\n"
    5724             :        JSON_STR)
    5725             : {
    5726           0 :         bool uj = use_json(argc, argv);
    5727           0 :         struct vrf *vrf;
    5728           0 :         bool first = true;
    5729           0 :         int idx = 2;
    5730             : 
    5731           0 :         char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx++]->arg
    5732           0 :                 : NULL;
    5733           0 :         char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx)
    5734           0 :                 ? argv[idx]->arg
    5735           0 :                 : NULL;
    5736             : 
    5737           0 :         if (uj)
    5738           0 :                 vty_out(vty, "{ ");
    5739           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
    5740           0 :                 if (uj) {
    5741           0 :                         if (!first)
    5742           0 :                                 vty_out(vty, ", ");
    5743           0 :                         vty_out(vty, " \"%s\": ", vrf->name);
    5744           0 :                         first = false;
    5745             :                 } else
    5746           0 :                         vty_out(vty, "VRF: %s\n", vrf->name);
    5747             : 
    5748           0 :                 if (src_ip && grp_ip)
    5749           0 :                         ip_msdp_show_sa_sg(vrf->info, vty, src_ip, grp_ip, uj);
    5750           0 :                 else if (src_ip)
    5751           0 :                         ip_msdp_show_sa_addr(vrf->info, vty, src_ip, uj);
    5752             :                 else
    5753           0 :                         ip_msdp_show_sa(vrf->info, vty, uj);
    5754             :         }
    5755           0 :         if (uj)
    5756           0 :                 vty_out(vty, "}\n");
    5757             : 
    5758           0 :         return CMD_SUCCESS;
    5759             : }
    5760             : 
    5761             : struct pim_sg_cache_walk_data {
    5762             :         struct vty *vty;
    5763             :         json_object *json;
    5764             :         json_object *json_group;
    5765             :         struct in_addr addr;
    5766             :         bool addr_match;
    5767             : };
    5768             : 
    5769           0 : static void pim_show_vxlan_sg_entry(struct pim_vxlan_sg *vxlan_sg,
    5770             :                                     struct pim_sg_cache_walk_data *cwd)
    5771             : {
    5772           0 :         struct vty *vty = cwd->vty;
    5773           0 :         json_object *json = cwd->json;
    5774           0 :         json_object *json_row;
    5775           0 :         bool installed = (vxlan_sg->up) ? true : false;
    5776           0 :         const char *iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
    5777           0 :         const char *oif_name;
    5778             : 
    5779           0 :         if (pim_vxlan_is_orig_mroute(vxlan_sg))
    5780           0 :                 oif_name = vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
    5781             :         else
    5782           0 :                 oif_name = vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
    5783             : 
    5784           0 :         if (cwd->addr_match && pim_addr_cmp(vxlan_sg->sg.src, cwd->addr) &&
    5785           0 :             pim_addr_cmp(vxlan_sg->sg.grp, cwd->addr)) {
    5786             :                 return;
    5787             :         }
    5788           0 :         if (json) {
    5789           0 :                 char src_str[PIM_ADDRSTRLEN];
    5790           0 :                 char grp_str[PIM_ADDRSTRLEN];
    5791             : 
    5792           0 :                 snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
    5793             :                            &vxlan_sg->sg.grp);
    5794           0 :                 snprintfrr(src_str, sizeof(src_str), "%pPAs",
    5795             :                            &vxlan_sg->sg.src);
    5796             : 
    5797           0 :                 json_object_object_get_ex(json, grp_str, &cwd->json_group);
    5798             : 
    5799           0 :                 if (!cwd->json_group) {
    5800           0 :                         cwd->json_group = json_object_new_object();
    5801           0 :                         json_object_object_add(json, grp_str,
    5802             :                                                cwd->json_group);
    5803             :                 }
    5804             : 
    5805           0 :                 json_row = json_object_new_object();
    5806           0 :                 json_object_string_add(json_row, "source", src_str);
    5807           0 :                 json_object_string_add(json_row, "group", grp_str);
    5808           0 :                 json_object_string_add(json_row, "input", iif_name);
    5809           0 :                 json_object_string_add(json_row, "output", oif_name);
    5810           0 :                 if (installed)
    5811           0 :                         json_object_boolean_true_add(json_row, "installed");
    5812             :                 else
    5813           0 :                         json_object_boolean_false_add(json_row, "installed");
    5814           0 :                 json_object_object_add(cwd->json_group, src_str, json_row);
    5815             :         } else {
    5816           0 :                 vty_out(vty, "%-15pPAs %-15pPAs %-15s %-15s %-5s\n",
    5817             :                         &vxlan_sg->sg.src, &vxlan_sg->sg.grp, iif_name,
    5818             :                         oif_name, installed ? "I" : "");
    5819             :         }
    5820             : }
    5821             : 
    5822           0 : static void pim_show_vxlan_sg_hash_entry(struct hash_bucket *bucket, void *arg)
    5823             : {
    5824           0 :         pim_show_vxlan_sg_entry((struct pim_vxlan_sg *)bucket->data,
    5825             :                                 (struct pim_sg_cache_walk_data *)arg);
    5826           0 : }
    5827             : 
    5828           0 : static void pim_show_vxlan_sg(struct pim_instance *pim,
    5829             :                               struct vty *vty, bool uj)
    5830             : {
    5831           0 :         json_object *json = NULL;
    5832           0 :         struct pim_sg_cache_walk_data cwd;
    5833             : 
    5834           0 :         if (uj) {
    5835           0 :                 json = json_object_new_object();
    5836             :         } else {
    5837           0 :                 vty_out(vty, "Codes: I -> installed\n");
    5838           0 :                 vty_out(vty,
    5839             :                         "Source          Group           Input           Output          Flags\n");
    5840             :         }
    5841             : 
    5842           0 :         memset(&cwd, 0, sizeof(cwd));
    5843           0 :         cwd.vty = vty;
    5844           0 :         cwd.json = json;
    5845           0 :         hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
    5846             : 
    5847           0 :         if (uj)
    5848           0 :                 vty_json(vty, json);
    5849           0 : }
    5850             : 
    5851           0 : static void pim_show_vxlan_sg_match_addr(struct pim_instance *pim,
    5852             :                                          struct vty *vty, char *addr_str,
    5853             :                                          bool uj)
    5854             : {
    5855           0 :         json_object *json = NULL;
    5856           0 :         struct pim_sg_cache_walk_data cwd;
    5857           0 :         int result = 0;
    5858             : 
    5859           0 :         memset(&cwd, 0, sizeof(cwd));
    5860           0 :         result = inet_pton(AF_INET, addr_str, &cwd.addr);
    5861           0 :         if (result <= 0) {
    5862           0 :                 vty_out(vty, "Bad address %s: errno=%d: %s\n", addr_str,
    5863           0 :                         errno, safe_strerror(errno));
    5864           0 :                 return;
    5865             :         }
    5866             : 
    5867           0 :         if (uj) {
    5868           0 :                 json = json_object_new_object();
    5869             :         } else {
    5870           0 :                 vty_out(vty, "Codes: I -> installed\n");
    5871           0 :                 vty_out(vty,
    5872             :                         "Source          Group           Input           Output          Flags\n");
    5873             :         }
    5874             : 
    5875           0 :         cwd.vty = vty;
    5876           0 :         cwd.json = json;
    5877           0 :         cwd.addr_match = true;
    5878           0 :         hash_iterate(pim->vxlan.sg_hash, pim_show_vxlan_sg_hash_entry, &cwd);
    5879             : 
    5880           0 :         if (uj)
    5881           0 :                 vty_json(vty, json);
    5882             : }
    5883             : 
    5884           0 : static void pim_show_vxlan_sg_one(struct pim_instance *pim,
    5885             :                                   struct vty *vty, char *src_str, char *grp_str,
    5886             :                                   bool uj)
    5887             : {
    5888           0 :         json_object *json = NULL;
    5889           0 :         pim_sgaddr sg;
    5890           0 :         int result = 0;
    5891           0 :         struct pim_vxlan_sg *vxlan_sg;
    5892           0 :         const char *iif_name;
    5893           0 :         bool installed;
    5894           0 :         const char *oif_name;
    5895             : 
    5896           0 :         result = inet_pton(AF_INET, src_str, &sg.src);
    5897           0 :         if (result <= 0) {
    5898           0 :                 vty_out(vty, "Bad src address %s: errno=%d: %s\n", src_str,
    5899           0 :                         errno, safe_strerror(errno));
    5900           0 :                 return;
    5901             :         }
    5902           0 :         result = inet_pton(AF_INET, grp_str, &sg.grp);
    5903           0 :         if (result <= 0) {
    5904           0 :                 vty_out(vty, "Bad grp address %s: errno=%d: %s\n", grp_str,
    5905           0 :                         errno, safe_strerror(errno));
    5906           0 :                 return;
    5907             :         }
    5908             : 
    5909           0 :         if (uj)
    5910           0 :                 json = json_object_new_object();
    5911             : 
    5912           0 :         vxlan_sg = pim_vxlan_sg_find(pim, &sg);
    5913           0 :         if (vxlan_sg) {
    5914           0 :                 installed = (vxlan_sg->up) ? true : false;
    5915           0 :                 iif_name = vxlan_sg->iif?vxlan_sg->iif->name:"-";
    5916             : 
    5917           0 :                 if (pim_vxlan_is_orig_mroute(vxlan_sg))
    5918           0 :                         oif_name =
    5919           0 :                                 vxlan_sg->orig_oif?vxlan_sg->orig_oif->name:"";
    5920             :                 else
    5921           0 :                         oif_name =
    5922           0 :                                 vxlan_sg->term_oif?vxlan_sg->term_oif->name:"";
    5923             : 
    5924           0 :                 if (uj) {
    5925           0 :                         json_object_string_add(json, "source", src_str);
    5926           0 :                         json_object_string_add(json, "group", grp_str);
    5927           0 :                         json_object_string_add(json, "input", iif_name);
    5928           0 :                         json_object_string_add(json, "output", oif_name);
    5929           0 :                         if (installed)
    5930           0 :                                 json_object_boolean_true_add(json, "installed");
    5931             :                         else
    5932           0 :                                 json_object_boolean_false_add(json,
    5933             :                                                               "installed");
    5934             :                 } else {
    5935           0 :                         vty_out(vty, "SG : %s\n", vxlan_sg->sg_str);
    5936           0 :                         vty_out(vty, "  Input     : %s\n", iif_name);
    5937           0 :                         vty_out(vty, "  Output    : %s\n", oif_name);
    5938           0 :                         vty_out(vty, "  installed : %s\n",
    5939             :                                 installed?"yes":"no");
    5940             :                 }
    5941             :         }
    5942             : 
    5943           0 :         if (uj)
    5944           0 :                 vty_json(vty, json);
    5945             : }
    5946             : 
    5947           0 : DEFUN (show_ip_pim_vxlan_sg,
    5948             :        show_ip_pim_vxlan_sg_cmd,
    5949             :        "show ip pim [vrf NAME] vxlan-groups [A.B.C.D [A.B.C.D]] [json]",
    5950             :        SHOW_STR
    5951             :        IP_STR
    5952             :        PIM_STR
    5953             :        VRF_CMD_HELP_STR
    5954             :        "VxLAN BUM groups\n"
    5955             :        "source or group ip\n"
    5956             :        "group ip\n"
    5957             :        JSON_STR)
    5958             : {
    5959           0 :         bool uj = use_json(argc, argv);
    5960           0 :         struct vrf *vrf;
    5961           0 :         int idx = 2;
    5962             : 
    5963           0 :         vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    5964             : 
    5965           0 :         if (!vrf)
    5966             :                 return CMD_WARNING;
    5967             : 
    5968           0 :         char *src_ip = argv_find(argv, argc, "A.B.C.D", &idx) ?
    5969           0 :                 argv[idx++]->arg:NULL;
    5970           0 :         char *grp_ip = idx < argc && argv_find(argv, argc, "A.B.C.D", &idx) ?
    5971           0 :                 argv[idx]->arg:NULL;
    5972             : 
    5973           0 :         if (src_ip && grp_ip)
    5974           0 :                 pim_show_vxlan_sg_one(vrf->info, vty, src_ip, grp_ip, uj);
    5975           0 :         else if (src_ip)
    5976           0 :                 pim_show_vxlan_sg_match_addr(vrf->info, vty, src_ip, uj);
    5977             :         else
    5978           0 :                 pim_show_vxlan_sg(vrf->info, vty, uj);
    5979             : 
    5980             :         return CMD_SUCCESS;
    5981             : }
    5982             : 
    5983           0 : static void pim_show_vxlan_sg_work(struct pim_instance *pim,
    5984             :                                    struct vty *vty, bool uj)
    5985             : {
    5986           0 :         json_object *json = NULL;
    5987           0 :         struct pim_sg_cache_walk_data cwd;
    5988           0 :         struct listnode *node;
    5989           0 :         struct pim_vxlan_sg *vxlan_sg;
    5990             : 
    5991           0 :         if (uj) {
    5992           0 :                 json = json_object_new_object();
    5993             :         } else {
    5994           0 :                 vty_out(vty, "Codes: I -> installed\n");
    5995           0 :                 vty_out(vty,
    5996             :                         "Source          Group           Input           Flags\n");
    5997             :         }
    5998             : 
    5999           0 :         memset(&cwd, 0, sizeof(cwd));
    6000           0 :         cwd.vty = vty;
    6001           0 :         cwd.json = json;
    6002           0 :         for (ALL_LIST_ELEMENTS_RO(pim_vxlan_p->work_list, node, vxlan_sg))
    6003           0 :                 pim_show_vxlan_sg_entry(vxlan_sg, &cwd);
    6004             : 
    6005           0 :         if (uj)
    6006           0 :                 vty_json(vty, json);
    6007           0 : }
    6008             : 
    6009           0 : DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
    6010             :               show_ip_pim_vxlan_sg_work_cmd,
    6011             :               "show ip pim [vrf NAME] vxlan-work [json]",
    6012             :               SHOW_STR
    6013             :               IP_STR
    6014             :               PIM_STR
    6015             :               VRF_CMD_HELP_STR
    6016             :               "VxLAN work list\n"
    6017             :               JSON_STR)
    6018             : {
    6019           0 :         bool uj = use_json(argc, argv);
    6020           0 :         struct vrf *vrf;
    6021           0 :         int idx = 2;
    6022             : 
    6023           0 :         vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
    6024             : 
    6025           0 :         if (!vrf)
    6026             :                 return CMD_WARNING;
    6027             : 
    6028           0 :         pim_show_vxlan_sg_work(vrf->info, vty, uj);
    6029             : 
    6030           0 :         return CMD_SUCCESS;
    6031             : }
    6032             : 
    6033           0 : DEFUN_HIDDEN (no_ip_pim_mlag,
    6034             :               no_ip_pim_mlag_cmd,
    6035             :               "no ip pim mlag",
    6036             :               NO_STR
    6037             :               IP_STR
    6038             :               PIM_STR
    6039             :               "MLAG\n")
    6040             : {
    6041           0 :         char mlag_xpath[XPATH_MAXLEN];
    6042             : 
    6043           0 :         snprintf(mlag_xpath, sizeof(mlag_xpath), FRR_PIM_VRF_XPATH,
    6044             :                  "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
    6045           0 :         strlcat(mlag_xpath, "/mlag", sizeof(mlag_xpath));
    6046             : 
    6047           0 :         nb_cli_enqueue_change(vty, mlag_xpath, NB_OP_DESTROY, NULL);
    6048             : 
    6049             : 
    6050           0 :         return nb_cli_apply_changes(vty, NULL);
    6051             : }
    6052             : 
    6053           0 : DEFUN_HIDDEN (ip_pim_mlag,
    6054             :               ip_pim_mlag_cmd,
    6055             :               "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D",
    6056             :               IP_STR
    6057             :               PIM_STR
    6058             :               "MLAG\n"
    6059             :               "peerlink sub interface\n"
    6060             :               "MLAG role\n"
    6061             :               "MLAG role primary\n"
    6062             :               "MLAG role secondary\n"
    6063             :               "peer session state\n"
    6064             :               "peer session state up\n"
    6065             :               "peer session state down\n"
    6066             :               "configure PIP\n"
    6067             :               "unique ip address\n")
    6068             : {
    6069           0 :         int idx;
    6070           0 :         char mlag_peerlink_rif_xpath[XPATH_MAXLEN];
    6071           0 :         char mlag_my_role_xpath[XPATH_MAXLEN];
    6072           0 :         char mlag_peer_state_xpath[XPATH_MAXLEN];
    6073           0 :         char mlag_reg_address_xpath[XPATH_MAXLEN];
    6074             : 
    6075           0 :         snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath),
    6076             :                  FRR_PIM_VRF_XPATH,
    6077             :                  "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
    6078           0 :         strlcat(mlag_peerlink_rif_xpath, "/mlag/peerlink-rif",
    6079             :                 sizeof(mlag_peerlink_rif_xpath));
    6080             : 
    6081           0 :         idx = 3;
    6082           0 :         nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY,
    6083           0 :                               argv[idx]->arg);
    6084             : 
    6085           0 :         snprintf(mlag_my_role_xpath, sizeof(mlag_my_role_xpath),
    6086             :                  FRR_PIM_VRF_XPATH,
    6087             :                  "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
    6088           0 :         strlcat(mlag_my_role_xpath, "/mlag/my-role",
    6089             :                 sizeof(mlag_my_role_xpath));
    6090             : 
    6091           0 :         idx += 2;
    6092           0 :         if (!strcmp(argv[idx]->arg, "primary")) {
    6093           0 :                 nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
    6094             :                                       "MLAG_ROLE_PRIMARY");
    6095             : 
    6096           0 :         } else if (!strcmp(argv[idx]->arg, "secondary")) {
    6097           0 :                 nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY,
    6098             :                                       "MLAG_ROLE_SECONDARY");
    6099             : 
    6100             :         } else {
    6101           0 :                 vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg);
    6102           0 :                 return CMD_WARNING;
    6103             :         }
    6104             : 
    6105           0 :         snprintf(mlag_peer_state_xpath, sizeof(mlag_peer_state_xpath),
    6106             :                  FRR_PIM_VRF_XPATH,
    6107             :                  "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
    6108           0 :         strlcat(mlag_peer_state_xpath, "/mlag/peer-state",
    6109             :                 sizeof(mlag_peer_state_xpath));
    6110             : 
    6111           0 :         idx += 2;
    6112           0 :         if (!strcmp(argv[idx]->arg, "up")) {
    6113           0 :                 nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
    6114             :                                       "true");
    6115             : 
    6116           0 :         } else if (strcmp(argv[idx]->arg, "down")) {
    6117           0 :                 nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY,
    6118             :                                       "false");
    6119             : 
    6120             :         } else {
    6121           0 :                 vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg);
    6122           0 :                 return CMD_WARNING;
    6123             :         }
    6124             : 
    6125           0 :         snprintf(mlag_reg_address_xpath, sizeof(mlag_reg_address_xpath),
    6126             :                  FRR_PIM_VRF_XPATH,
    6127             :                  "frr-pim:pimd", "pim", "default", "frr-routing:ipv4");
    6128           0 :         strlcat(mlag_reg_address_xpath, "/mlag/reg-address",
    6129             :                 sizeof(mlag_reg_address_xpath));
    6130             : 
    6131           0 :         idx += 2;
    6132           0 :         nb_cli_enqueue_change(vty, mlag_reg_address_xpath, NB_OP_MODIFY,
    6133           0 :                               argv[idx]->arg);
    6134             : 
    6135           0 :         return nb_cli_apply_changes(vty, NULL);
    6136             : }
    6137             : 
    6138           3 : void pim_cmd_init(void)
    6139             : {
    6140           3 :         if_cmd_init(pim_interface_config_write);
    6141             : 
    6142           3 :         install_node(&debug_node);
    6143             : 
    6144           3 :         install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd);
    6145             : 
    6146           3 :         install_element(CONFIG_NODE, &ip_pim_rp_cmd);
    6147           3 :         install_element(VRF_NODE, &ip_pim_rp_cmd);
    6148           3 :         install_element(CONFIG_NODE, &no_ip_pim_rp_cmd);
    6149           3 :         install_element(VRF_NODE, &no_ip_pim_rp_cmd);
    6150           3 :         install_element(CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
    6151           3 :         install_element(VRF_NODE, &ip_pim_rp_prefix_list_cmd);
    6152           3 :         install_element(CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
    6153           3 :         install_element(VRF_NODE, &no_ip_pim_rp_prefix_list_cmd);
    6154           3 :         install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
    6155           3 :         install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_cmd);
    6156           3 :         install_element(CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
    6157           3 :         install_element(VRF_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
    6158           3 :         install_element(CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
    6159           3 :         install_element(VRF_NODE, &ip_pim_ssm_prefix_list_cmd);
    6160           3 :         install_element(CONFIG_NODE, &ip_pim_register_suppress_cmd);
    6161           3 :         install_element(CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
    6162           3 :         install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_cmd);
    6163           3 :         install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_cmd);
    6164           3 :         install_element(CONFIG_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
    6165           3 :         install_element(VRF_NODE, &ip_pim_spt_switchover_infinity_plist_cmd);
    6166           3 :         install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
    6167           3 :         install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_cmd);
    6168           3 :         install_element(CONFIG_NODE,
    6169             :                         &no_ip_pim_spt_switchover_infinity_plist_cmd);
    6170           3 :         install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd);
    6171           3 :         install_element(CONFIG_NODE, &pim_register_accept_list_cmd);
    6172           3 :         install_element(VRF_NODE, &pim_register_accept_list_cmd);
    6173           3 :         install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd);
    6174           3 :         install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
    6175           3 :         install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd);
    6176           3 :         install_element(VRF_NODE, &ip_pim_keep_alive_cmd);
    6177           3 :         install_element(CONFIG_NODE, &ip_pim_rp_keep_alive_cmd);
    6178           3 :         install_element(VRF_NODE, &ip_pim_rp_keep_alive_cmd);
    6179           3 :         install_element(CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
    6180           3 :         install_element(VRF_NODE, &no_ip_pim_keep_alive_cmd);
    6181           3 :         install_element(CONFIG_NODE, &no_ip_pim_rp_keep_alive_cmd);
    6182           3 :         install_element(VRF_NODE, &no_ip_pim_rp_keep_alive_cmd);
    6183           3 :         install_element(CONFIG_NODE, &ip_pim_packets_cmd);
    6184           3 :         install_element(CONFIG_NODE, &no_ip_pim_packets_cmd);
    6185           3 :         install_element(CONFIG_NODE, &ip_pim_v6_secondary_cmd);
    6186           3 :         install_element(VRF_NODE, &ip_pim_v6_secondary_cmd);
    6187           3 :         install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
    6188           3 :         install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd);
    6189           3 :         install_element(CONFIG_NODE, &ip_ssmpingd_cmd);
    6190           3 :         install_element(VRF_NODE, &ip_ssmpingd_cmd);
    6191           3 :         install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd);
    6192           3 :         install_element(VRF_NODE, &no_ip_ssmpingd_cmd);
    6193           3 :         install_element(CONFIG_NODE, &ip_msdp_peer_cmd);
    6194           3 :         install_element(VRF_NODE, &ip_msdp_peer_cmd);
    6195           3 :         install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd);
    6196           3 :         install_element(VRF_NODE, &no_ip_msdp_peer_cmd);
    6197           3 :         install_element(CONFIG_NODE, &ip_pim_ecmp_cmd);
    6198           3 :         install_element(VRF_NODE, &ip_pim_ecmp_cmd);
    6199           3 :         install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd);
    6200           3 :         install_element(VRF_NODE, &no_ip_pim_ecmp_cmd);
    6201           3 :         install_element(CONFIG_NODE, &ip_pim_ecmp_rebalance_cmd);
    6202           3 :         install_element(VRF_NODE, &ip_pim_ecmp_rebalance_cmd);
    6203           3 :         install_element(CONFIG_NODE, &no_ip_pim_ecmp_rebalance_cmd);
    6204           3 :         install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
    6205           3 :         install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
    6206           3 :         install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
    6207           3 :         install_element(CONFIG_NODE, &ip_igmp_group_watermark_cmd);
    6208           3 :         install_element(VRF_NODE, &ip_igmp_group_watermark_cmd);
    6209           3 :         install_element(CONFIG_NODE, &no_ip_igmp_group_watermark_cmd);
    6210           3 :         install_element(VRF_NODE, &no_ip_igmp_group_watermark_cmd);
    6211             : 
    6212           3 :         install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
    6213           3 :         install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
    6214           3 :         install_element(INTERFACE_NODE, &interface_ip_igmp_join_cmd);
    6215           3 :         install_element(INTERFACE_NODE, &interface_no_ip_igmp_join_cmd);
    6216           3 :         install_element(INTERFACE_NODE, &interface_ip_igmp_version_cmd);
    6217           3 :         install_element(INTERFACE_NODE, &interface_no_ip_igmp_version_cmd);
    6218           3 :         install_element(INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
    6219           3 :         install_element(INTERFACE_NODE,
    6220             :                         &interface_no_ip_igmp_query_interval_cmd);
    6221           3 :         install_element(INTERFACE_NODE,
    6222             :                         &interface_ip_igmp_query_max_response_time_cmd);
    6223           3 :         install_element(INTERFACE_NODE,
    6224             :                         &interface_no_ip_igmp_query_max_response_time_cmd);
    6225           3 :         install_element(INTERFACE_NODE,
    6226             :                         &interface_ip_igmp_query_max_response_time_dsec_cmd);
    6227           3 :         install_element(INTERFACE_NODE,
    6228             :                         &interface_no_ip_igmp_query_max_response_time_dsec_cmd);
    6229           3 :         install_element(INTERFACE_NODE,
    6230             :                         &interface_ip_igmp_last_member_query_count_cmd);
    6231           3 :         install_element(INTERFACE_NODE,
    6232             :                         &interface_no_ip_igmp_last_member_query_count_cmd);
    6233           3 :         install_element(INTERFACE_NODE,
    6234             :                         &interface_ip_igmp_last_member_query_interval_cmd);
    6235           3 :         install_element(INTERFACE_NODE,
    6236             :                         &interface_no_ip_igmp_last_member_query_interval_cmd);
    6237           3 :         install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);
    6238           3 :         install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
    6239           3 :         install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
    6240           3 :         install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd);
    6241           3 :         install_element(INTERFACE_NODE, &interface_no_ip_pim_sm_cmd);
    6242           3 :         install_element(INTERFACE_NODE, &interface_ip_pim_cmd);
    6243           3 :         install_element(INTERFACE_NODE, &interface_no_ip_pim_cmd);
    6244           3 :         install_element(INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
    6245           3 :         install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
    6246           3 :         install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
    6247           3 :         install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
    6248           3 :         install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
    6249           3 :         install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
    6250           3 :         install_element(INTERFACE_NODE, &interface_ip_igmp_query_generate_cmd);
    6251             : 
    6252             :         // Static mroutes NEB
    6253           3 :         install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
    6254           3 :         install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd);
    6255             : 
    6256           3 :         install_element(VIEW_NODE, &show_ip_igmp_interface_cmd);
    6257           3 :         install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd);
    6258           3 :         install_element(VIEW_NODE, &show_ip_igmp_join_cmd);
    6259           3 :         install_element(VIEW_NODE, &show_ip_igmp_join_vrf_all_cmd);
    6260           3 :         install_element(VIEW_NODE, &show_ip_igmp_groups_cmd);
    6261           3 :         install_element(VIEW_NODE, &show_ip_igmp_groups_vrf_all_cmd);
    6262           3 :         install_element(VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
    6263           3 :         install_element(VIEW_NODE, &show_ip_igmp_sources_cmd);
    6264           3 :         install_element(VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
    6265           3 :         install_element(VIEW_NODE, &show_ip_igmp_statistics_cmd);
    6266           3 :         install_element(VIEW_NODE, &show_ip_pim_assert_cmd);
    6267           3 :         install_element(VIEW_NODE, &show_ip_pim_assert_internal_cmd);
    6268           3 :         install_element(VIEW_NODE, &show_ip_pim_assert_metric_cmd);
    6269           3 :         install_element(VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
    6270           3 :         install_element(VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
    6271           3 :         install_element(VIEW_NODE, &show_ip_pim_interface_cmd);
    6272           3 :         install_element(VIEW_NODE, &show_ip_pim_interface_vrf_all_cmd);
    6273           3 :         install_element(VIEW_NODE, &show_ip_pim_join_cmd);
    6274           3 :         install_element(VIEW_NODE, &show_ip_pim_join_vrf_all_cmd);
    6275           3 :         install_element(VIEW_NODE, &show_ip_pim_jp_agg_cmd);
    6276           3 :         install_element(VIEW_NODE, &show_ip_pim_local_membership_cmd);
    6277           3 :         install_element(VIEW_NODE, &show_ip_pim_mlag_summary_cmd);
    6278           3 :         install_element(VIEW_NODE, &show_ip_pim_mlag_up_cmd);
    6279           3 :         install_element(VIEW_NODE, &show_ip_pim_mlag_up_vrf_all_cmd);
    6280           3 :         install_element(VIEW_NODE, &show_ip_pim_neighbor_cmd);
    6281           3 :         install_element(VIEW_NODE, &show_ip_pim_neighbor_vrf_all_cmd);
    6282           3 :         install_element(VIEW_NODE, &show_ip_pim_rpf_cmd);
    6283           3 :         install_element(VIEW_NODE, &show_ip_pim_rpf_vrf_all_cmd);
    6284           3 :         install_element(VIEW_NODE, &show_ip_pim_secondary_cmd);
    6285           3 :         install_element(VIEW_NODE, &show_ip_pim_state_cmd);
    6286           3 :         install_element(VIEW_NODE, &show_ip_pim_state_vrf_all_cmd);
    6287           3 :         install_element(VIEW_NODE, &show_ip_pim_upstream_cmd);
    6288           3 :         install_element(VIEW_NODE, &show_ip_pim_upstream_vrf_all_cmd);
    6289           3 :         install_element(VIEW_NODE, &show_ip_pim_channel_cmd);
    6290           3 :         install_element(VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
    6291           3 :         install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
    6292           3 :         install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
    6293           3 :         install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
    6294           3 :         install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
    6295           3 :         install_element(VIEW_NODE, &show_ip_multicast_cmd);
    6296           3 :         install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
    6297           3 :         install_element(VIEW_NODE, &show_ip_multicast_count_cmd);
    6298           3 :         install_element(VIEW_NODE, &show_ip_multicast_count_vrf_all_cmd);
    6299           3 :         install_element(VIEW_NODE, &show_ip_mroute_cmd);
    6300           3 :         install_element(VIEW_NODE, &show_ip_mroute_vrf_all_cmd);
    6301           3 :         install_element(VIEW_NODE, &show_ip_mroute_count_cmd);
    6302           3 :         install_element(VIEW_NODE, &show_ip_mroute_count_vrf_all_cmd);
    6303           3 :         install_element(VIEW_NODE, &show_ip_mroute_summary_cmd);
    6304           3 :         install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
    6305           3 :         install_element(VIEW_NODE, &show_ip_rib_cmd);
    6306           3 :         install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
    6307           3 :         install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
    6308           3 :         install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
    6309           3 :         install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
    6310           3 :         install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
    6311           3 :         install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
    6312             : 
    6313           3 :         install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
    6314           3 :         install_element(ENABLE_NODE, &clear_ip_interfaces_cmd);
    6315           3 :         install_element(ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
    6316           3 :         install_element(ENABLE_NODE, &clear_ip_mroute_cmd);
    6317           3 :         install_element(ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
    6318           3 :         install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
    6319           3 :         install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
    6320           3 :         install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
    6321           3 :         install_element(ENABLE_NODE, &clear_ip_pim_bsr_db_cmd);
    6322             : 
    6323           3 :         install_element(ENABLE_NODE, &show_debugging_pim_cmd);
    6324             : 
    6325           3 :         install_element(ENABLE_NODE, &debug_igmp_cmd);
    6326           3 :         install_element(ENABLE_NODE, &no_debug_igmp_cmd);
    6327           3 :         install_element(ENABLE_NODE, &debug_igmp_events_cmd);
    6328           3 :         install_element(ENABLE_NODE, &no_debug_igmp_events_cmd);
    6329           3 :         install_element(ENABLE_NODE, &debug_igmp_packets_cmd);
    6330           3 :         install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd);
    6331           3 :         install_element(ENABLE_NODE, &debug_igmp_trace_cmd);
    6332           3 :         install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd);
    6333           3 :         install_element(ENABLE_NODE, &debug_igmp_trace_detail_cmd);
    6334           3 :         install_element(ENABLE_NODE, &no_debug_igmp_trace_detail_cmd);
    6335           3 :         install_element(ENABLE_NODE, &debug_mroute_cmd);
    6336           3 :         install_element(ENABLE_NODE, &debug_mroute_detail_cmd);
    6337           3 :         install_element(ENABLE_NODE, &no_debug_mroute_cmd);
    6338           3 :         install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd);
    6339           3 :         install_element(ENABLE_NODE, &debug_pim_static_cmd);
    6340           3 :         install_element(ENABLE_NODE, &no_debug_pim_static_cmd);
    6341           3 :         install_element(ENABLE_NODE, &debug_pim_cmd);
    6342           3 :         install_element(ENABLE_NODE, &debug_pim_nht_cmd);
    6343           3 :         install_element(ENABLE_NODE, &debug_pim_nht_det_cmd);
    6344           3 :         install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd);
    6345           3 :         install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd);
    6346           3 :         install_element(ENABLE_NODE, &debug_pim_events_cmd);
    6347           3 :         install_element(ENABLE_NODE, &debug_pim_packets_cmd);
    6348           3 :         install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd);
    6349           3 :         install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
    6350           3 :         install_element(ENABLE_NODE, &debug_pim_trace_cmd);
    6351           3 :         install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd);
    6352           3 :         install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
    6353           3 :         install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
    6354           3 :         install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
    6355           3 :         install_element(ENABLE_NODE, &debug_pim_mlag_cmd);
    6356           3 :         install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd);
    6357           3 :         install_element(ENABLE_NODE, &debug_pim_vxlan_cmd);
    6358           3 :         install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd);
    6359           3 :         install_element(ENABLE_NODE, &debug_msdp_cmd);
    6360           3 :         install_element(ENABLE_NODE, &no_debug_msdp_cmd);
    6361           3 :         install_element(ENABLE_NODE, &debug_msdp_events_cmd);
    6362           3 :         install_element(ENABLE_NODE, &no_debug_msdp_events_cmd);
    6363           3 :         install_element(ENABLE_NODE, &debug_msdp_packets_cmd);
    6364           3 :         install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd);
    6365           3 :         install_element(ENABLE_NODE, &debug_mtrace_cmd);
    6366           3 :         install_element(ENABLE_NODE, &no_debug_mtrace_cmd);
    6367           3 :         install_element(ENABLE_NODE, &debug_bsm_cmd);
    6368           3 :         install_element(ENABLE_NODE, &no_debug_bsm_cmd);
    6369             : 
    6370           3 :         install_element(CONFIG_NODE, &debug_igmp_cmd);
    6371           3 :         install_element(CONFIG_NODE, &no_debug_igmp_cmd);
    6372           3 :         install_element(CONFIG_NODE, &debug_igmp_events_cmd);
    6373           3 :         install_element(CONFIG_NODE, &no_debug_igmp_events_cmd);
    6374           3 :         install_element(CONFIG_NODE, &debug_igmp_packets_cmd);
    6375           3 :         install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd);
    6376           3 :         install_element(CONFIG_NODE, &debug_igmp_trace_cmd);
    6377           3 :         install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd);
    6378           3 :         install_element(CONFIG_NODE, &debug_igmp_trace_detail_cmd);
    6379           3 :         install_element(CONFIG_NODE, &no_debug_igmp_trace_detail_cmd);
    6380           3 :         install_element(CONFIG_NODE, &debug_mroute_cmd);
    6381           3 :         install_element(CONFIG_NODE, &debug_mroute_detail_cmd);
    6382           3 :         install_element(CONFIG_NODE, &no_debug_mroute_cmd);
    6383           3 :         install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd);
    6384           3 :         install_element(CONFIG_NODE, &debug_pim_static_cmd);
    6385           3 :         install_element(CONFIG_NODE, &no_debug_pim_static_cmd);
    6386           3 :         install_element(CONFIG_NODE, &debug_pim_cmd);
    6387           3 :         install_element(CONFIG_NODE, &debug_pim_nht_cmd);
    6388           3 :         install_element(CONFIG_NODE, &debug_pim_nht_det_cmd);
    6389           3 :         install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd);
    6390           3 :         install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd);
    6391           3 :         install_element(CONFIG_NODE, &debug_pim_events_cmd);
    6392           3 :         install_element(CONFIG_NODE, &debug_pim_packets_cmd);
    6393           3 :         install_element(CONFIG_NODE, &debug_pim_packetdump_send_cmd);
    6394           3 :         install_element(CONFIG_NODE, &debug_pim_packetdump_recv_cmd);
    6395           3 :         install_element(CONFIG_NODE, &debug_pim_trace_cmd);
    6396           3 :         install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
    6397           3 :         install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
    6398           3 :         install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
    6399           3 :         install_element(CONFIG_NODE, &debug_pim_zebra_cmd);
    6400           3 :         install_element(CONFIG_NODE, &debug_pim_mlag_cmd);
    6401           3 :         install_element(CONFIG_NODE, &no_debug_pim_mlag_cmd);
    6402           3 :         install_element(CONFIG_NODE, &debug_pim_vxlan_cmd);
    6403           3 :         install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd);
    6404           3 :         install_element(CONFIG_NODE, &debug_msdp_cmd);
    6405           3 :         install_element(CONFIG_NODE, &no_debug_msdp_cmd);
    6406           3 :         install_element(CONFIG_NODE, &debug_msdp_events_cmd);
    6407           3 :         install_element(CONFIG_NODE, &no_debug_msdp_events_cmd);
    6408           3 :         install_element(CONFIG_NODE, &debug_msdp_packets_cmd);
    6409           3 :         install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd);
    6410           3 :         install_element(CONFIG_NODE, &debug_mtrace_cmd);
    6411           3 :         install_element(CONFIG_NODE, &no_debug_mtrace_cmd);
    6412           3 :         install_element(CONFIG_NODE, &debug_bsm_cmd);
    6413           3 :         install_element(CONFIG_NODE, &no_debug_bsm_cmd);
    6414             : 
    6415           3 :         install_element(CONFIG_NODE, &ip_msdp_timers_cmd);
    6416           3 :         install_element(VRF_NODE, &ip_msdp_timers_cmd);
    6417           3 :         install_element(CONFIG_NODE, &no_ip_msdp_timers_cmd);
    6418           3 :         install_element(VRF_NODE, &no_ip_msdp_timers_cmd);
    6419           3 :         install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
    6420           3 :         install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
    6421           3 :         install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
    6422           3 :         install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd);
    6423           3 :         install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
    6424           3 :         install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd);
    6425           3 :         install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd);
    6426           3 :         install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd);
    6427           3 :         install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_cmd);
    6428           3 :         install_element(VRF_NODE, &no_ip_msdp_mesh_group_cmd);
    6429           3 :         install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd);
    6430           3 :         install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd);
    6431           3 :         install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
    6432           3 :         install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd);
    6433           3 :         install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
    6434           3 :         install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd);
    6435           3 :         install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
    6436           3 :         install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd);
    6437           3 :         install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd);
    6438           3 :         install_element(VIEW_NODE, &show_ip_pim_group_type_cmd);
    6439           3 :         install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd);
    6440           3 :         install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd);
    6441           3 :         install_element(INTERFACE_NODE, &interface_pim_use_source_cmd);
    6442           3 :         install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd);
    6443             :         /* Install BSM command */
    6444           3 :         install_element(INTERFACE_NODE, &ip_pim_bsm_cmd);
    6445           3 :         install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd);
    6446           3 :         install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd);
    6447           3 :         install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd);
    6448             :         /* Install BFD command */
    6449           3 :         install_element(INTERFACE_NODE, &ip_pim_bfd_cmd);
    6450           3 :         install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd);
    6451           3 :         install_element(INTERFACE_NODE, &no_ip_pim_bfd_profile_cmd);
    6452           3 :         install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd);
    6453             : #if HAVE_BFDD == 0
    6454             :         install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
    6455             : #endif /* !HAVE_BFDD */
    6456           3 : }

Generated by: LCOV version v1.16-topotato