File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / pimd / pim_cmd.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:11 2016 UTC (8 years, 7 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    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
   16:   along with this program; see the file COPYING; if not, write to the
   17:   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
   18:   MA 02110-1301 USA
   19:   
   20:   $QuaggaId: $Format:%an, %ai, %h$ $
   21: */
   22: 
   23: #include <zebra.h>
   24: 
   25: #include <sys/ioctl.h>
   26: 
   27: #include "command.h"
   28: #include "if.h"
   29: #include "prefix.h"
   30: #include "zclient.h"
   31: 
   32: #include "pimd.h"
   33: #include "pim_cmd.h"
   34: #include "pim_iface.h"
   35: #include "pim_vty.h"
   36: #include "pim_mroute.h"
   37: #include "pim_str.h"
   38: #include "pim_igmp.h"
   39: #include "pim_igmpv3.h"
   40: #include "pim_sock.h"
   41: #include "pim_time.h"
   42: #include "pim_util.h"
   43: #include "pim_oil.h"
   44: #include "pim_neighbor.h"
   45: #include "pim_pim.h"
   46: #include "pim_ifchannel.h"
   47: #include "pim_hello.h"
   48: #include "pim_msg.h"
   49: #include "pim_upstream.h"
   50: #include "pim_rpf.h"
   51: #include "pim_macro.h"
   52: #include "pim_ssmpingd.h"
   53: #include "pim_zebra.h"
   54: #include "pim_static.h"
   55: 
   56: static struct cmd_node pim_global_node = {
   57:   PIM_NODE,
   58:   "",
   59:   1 /* vtysh ? yes */
   60: };
   61: 
   62: static struct cmd_node interface_node = {
   63:   INTERFACE_NODE,
   64:   "%s(config-if)# ",
   65:   1 /* vtysh ? yes */
   66: };
   67: 
   68: static void pim_if_membership_clear(struct interface *ifp)
   69: {
   70:   struct pim_interface *pim_ifp;
   71: 
   72:   pim_ifp = ifp->info;
   73:   zassert(pim_ifp);
   74: 
   75:   if (PIM_IF_TEST_PIM(pim_ifp->options) &&
   76:       PIM_IF_TEST_IGMP(pim_ifp->options)) {
   77:     return;
   78:   }
   79: 
   80:   pim_ifchannel_membership_clear(ifp);
   81: }
   82: 
   83: /*
   84:   When PIM is disabled on interface, IGMPv3 local membership
   85:   information is not injected into PIM interface state.
   86: 
   87:   The function pim_if_membership_refresh() fetches all IGMPv3 local
   88:   membership information into PIM. It is intented to be called
   89:   whenever PIM is enabled on the interface in order to collect missed
   90:   local membership information.
   91:  */
   92: static void pim_if_membership_refresh(struct interface *ifp)
   93: {
   94:   struct pim_interface *pim_ifp;
   95:   struct listnode      *sock_node;
   96:   struct igmp_sock     *igmp;
   97: 
   98:   pim_ifp = ifp->info;
   99:   zassert(pim_ifp);
  100: 
  101:   if (!PIM_IF_TEST_PIM(pim_ifp->options))
  102:     return;
  103:   if (!PIM_IF_TEST_IGMP(pim_ifp->options))
  104:     return;
  105: 
  106:   /*
  107:     First clear off membership from all PIM (S,G) entries on the
  108:     interface
  109:   */
  110: 
  111:   pim_ifchannel_membership_clear(ifp);
  112: 
  113:   /*
  114:     Then restore PIM (S,G) membership from all IGMPv3 (S,G) entries on
  115:     the interface
  116:   */
  117: 
  118:   /* scan igmp sockets */
  119:   for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  120:     struct listnode   *grpnode;
  121:     struct igmp_group *grp;
  122:     
  123:     /* scan igmp groups */
  124:     for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
  125:       struct listnode    *srcnode;
  126:       struct igmp_source *src;
  127:       
  128:       /* scan group sources */
  129:       for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
  130: 
  131: 	if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) {
  132: 	  pim_ifchannel_local_membership_add(ifp,
  133: 					     src->source_addr,
  134: 					     grp->group_addr);
  135: 	}
  136: 	
  137:       } /* scan group sources */
  138:     } /* scan igmp groups */
  139:   } /* scan igmp sockets */
  140: 
  141:   /*
  142:     Finally delete every PIM (S,G) entry lacking all state info
  143:    */
  144: 
  145:   pim_ifchannel_delete_on_noinfo(ifp);
  146: 
  147: }
  148: 
  149: static void pim_show_assert(struct vty *vty)
  150: {
  151:   struct listnode  *ifnode;
  152:   struct interface *ifp;
  153:   time_t            now;
  154:   
  155:   now = pim_time_monotonic_sec();
  156: 
  157:   vty_out(vty,
  158: 	  "Interface Address         Source          Group           State  Winner          Uptime   Timer%s",
  159: 	  VTY_NEWLINE);
  160: 
  161:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  162:     struct pim_interface *pim_ifp;
  163:     struct in_addr ifaddr;
  164:     struct listnode *ch_node;
  165:     struct pim_ifchannel *ch;
  166: 
  167:     pim_ifp = ifp->info;
  168:     
  169:     if (!pim_ifp)
  170:       continue;
  171: 
  172:     ifaddr = pim_ifp->primary_address;
  173: 
  174:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  175:       char ch_src_str[100];
  176:       char ch_grp_str[100];
  177:       char winner_str[100];
  178:       char uptime[10];
  179:       char timer[10];
  180: 
  181:       pim_inet4_dump("<ch_src?>", ch->source_addr,
  182: 		     ch_src_str, sizeof(ch_src_str));
  183:       pim_inet4_dump("<ch_grp?>", ch->group_addr,
  184: 		     ch_grp_str, sizeof(ch_grp_str));
  185:       pim_inet4_dump("<assrt_win?>", ch->ifassert_winner,
  186: 		     winner_str, sizeof(winner_str));
  187: 
  188:       pim_time_uptime(uptime, sizeof(uptime), now - ch->ifassert_creation);
  189:       pim_time_timer_to_mmss(timer, sizeof(timer),
  190: 			     ch->t_ifassert_timer);
  191: 
  192:       vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %-15s %-8s %-5s%s",
  193: 	      ifp->name,
  194: 	      inet_ntoa(ifaddr),
  195: 	      ch_src_str,
  196: 	      ch_grp_str,
  197: 	      pim_ifchannel_ifassert_name(ch->ifassert_state),
  198: 	      winner_str,
  199: 	      uptime,
  200: 	      timer,
  201: 	      VTY_NEWLINE);
  202:     } /* scan interface channels */
  203:   } /* scan interfaces */
  204: }
  205: 
  206: static void pim_show_assert_internal(struct vty *vty)
  207: {
  208:   struct listnode  *ifnode;
  209:   struct interface *ifp;
  210: 
  211:   vty_out(vty,
  212: 	  "CA:   CouldAssert%s"
  213: 	  "ECA:  Evaluate CouldAssert%s"
  214: 	  "ATD:  AssertTrackingDesired%s"
  215: 	  "eATD: Evaluate AssertTrackingDesired%s%s",
  216: 	  VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  217: 
  218:   vty_out(vty,
  219: 	  "Interface Address         Source          Group           CA  eCA ATD eATD%s",
  220: 	  VTY_NEWLINE);
  221: 
  222:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  223:     struct pim_interface *pim_ifp;
  224:     struct in_addr ifaddr;
  225:     struct listnode *ch_node;
  226:     struct pim_ifchannel *ch;
  227: 
  228:     pim_ifp = ifp->info;
  229:     
  230:     if (!pim_ifp)
  231:       continue;
  232: 
  233:     ifaddr = pim_ifp->primary_address;
  234: 
  235:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  236:       char ch_src_str[100];
  237:       char ch_grp_str[100];
  238: 
  239:       pim_inet4_dump("<ch_src?>", ch->source_addr,
  240: 		     ch_src_str, sizeof(ch_src_str));
  241:       pim_inet4_dump("<ch_grp?>", ch->group_addr,
  242: 		     ch_grp_str, sizeof(ch_grp_str));
  243:       vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-3s %-3s %-4s%s",
  244: 	      ifp->name,
  245: 	      inet_ntoa(ifaddr),
  246: 	      ch_src_str,
  247: 	      ch_grp_str,
  248: 	      PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
  249: 	      pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
  250: 	      PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes" : "no",
  251: 	      pim_macro_assert_tracking_desired_eval(ch) ? "yes" : "no",
  252: 	      VTY_NEWLINE);
  253:     } /* scan interface channels */
  254:   } /* scan interfaces */
  255: }
  256: 
  257: static void pim_show_assert_metric(struct vty *vty)
  258: {
  259:   struct listnode  *ifnode;
  260:   struct interface *ifp;
  261:   
  262:   vty_out(vty,
  263: 	  "Interface Address         Source          Group           RPT Pref Metric Address        %s",
  264: 	  VTY_NEWLINE);
  265: 
  266:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  267:     struct pim_interface *pim_ifp;
  268:     struct in_addr ifaddr;
  269:     struct listnode *ch_node;
  270:     struct pim_ifchannel *ch;
  271: 
  272:     pim_ifp = ifp->info;
  273:     
  274:     if (!pim_ifp)
  275:       continue;
  276: 
  277:     ifaddr = pim_ifp->primary_address;
  278: 
  279:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  280:       char ch_src_str[100];
  281:       char ch_grp_str[100];
  282:       char addr_str[100];
  283:       struct pim_assert_metric am;
  284: 
  285:       am = pim_macro_spt_assert_metric(&ch->upstream->rpf, pim_ifp->primary_address);
  286: 
  287:       pim_inet4_dump("<ch_src?>", ch->source_addr,
  288: 		     ch_src_str, sizeof(ch_src_str));
  289:       pim_inet4_dump("<ch_grp?>", ch->group_addr,
  290: 		     ch_grp_str, sizeof(ch_grp_str));
  291:       pim_inet4_dump("<addr?>", am.ip_address,
  292: 		     addr_str, sizeof(addr_str));
  293: 
  294:       vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %4u %6u %-15s%s",
  295: 	      ifp->name,
  296: 	      inet_ntoa(ifaddr),
  297: 	      ch_src_str,
  298: 	      ch_grp_str,
  299: 	      am.rpt_bit_flag ? "yes" : "no",
  300: 	      am.metric_preference,
  301: 	      am.route_metric,
  302: 	      addr_str,
  303: 	      VTY_NEWLINE);
  304:     } /* scan interface channels */
  305:   } /* scan interfaces */
  306: }
  307: 
  308: static void pim_show_assert_winner_metric(struct vty *vty)
  309: {
  310:   struct listnode  *ifnode;
  311:   struct interface *ifp;
  312:   
  313:   vty_out(vty,
  314: 	  "Interface Address         Source          Group           RPT Pref Metric Address        %s",
  315: 	  VTY_NEWLINE);
  316: 
  317:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  318:     struct pim_interface *pim_ifp;
  319:     struct in_addr ifaddr;
  320:     struct listnode *ch_node;
  321:     struct pim_ifchannel *ch;
  322: 
  323:     pim_ifp = ifp->info;
  324:     
  325:     if (!pim_ifp)
  326:       continue;
  327: 
  328:     ifaddr = pim_ifp->primary_address;
  329: 
  330:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  331:       char ch_src_str[100];
  332:       char ch_grp_str[100];
  333:       char addr_str[100];
  334:       struct pim_assert_metric *am;
  335:       char pref_str[5];
  336:       char metr_str[7];
  337: 
  338:       am = &ch->ifassert_winner_metric;
  339: 
  340:       pim_inet4_dump("<ch_src?>", ch->source_addr,
  341: 		     ch_src_str, sizeof(ch_src_str));
  342:       pim_inet4_dump("<ch_grp?>", ch->group_addr,
  343: 		     ch_grp_str, sizeof(ch_grp_str));
  344:       pim_inet4_dump("<addr?>", am->ip_address,
  345: 		     addr_str, sizeof(addr_str));
  346: 
  347:       if (am->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
  348: 	snprintf(pref_str, sizeof(pref_str), "INFI");
  349:       else
  350: 	snprintf(pref_str, sizeof(pref_str), "%4u", am->metric_preference);
  351: 
  352:       if (am->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX)
  353: 	snprintf(metr_str, sizeof(metr_str), "INFI");
  354:       else
  355: 	snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
  356: 
  357:       vty_out(vty, "%-9s %-15s %-15s %-15s %-3s %-4s %-6s %-15s%s",
  358: 	      ifp->name,
  359: 	      inet_ntoa(ifaddr),
  360: 	      ch_src_str,
  361: 	      ch_grp_str,
  362: 	      am->rpt_bit_flag ? "yes" : "no",
  363: 	      pref_str,
  364: 	      metr_str,
  365: 	      addr_str,
  366: 	      VTY_NEWLINE);
  367:     } /* scan interface channels */
  368:   } /* scan interfaces */
  369: }
  370: 
  371: static void pim_show_membership(struct vty *vty)
  372: {
  373:   struct listnode  *ifnode;
  374:   struct interface *ifp;
  375: 
  376:   vty_out(vty,
  377: 	  "Interface Address         Source          Group           Membership%s",
  378: 	  VTY_NEWLINE);
  379: 
  380:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  381:     struct pim_interface *pim_ifp;
  382:     struct in_addr ifaddr;
  383:     struct listnode *ch_node;
  384:     struct pim_ifchannel *ch;
  385: 
  386:     pim_ifp = ifp->info;
  387:     
  388:     if (!pim_ifp)
  389:       continue;
  390: 
  391:     ifaddr = pim_ifp->primary_address;
  392: 
  393:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  394:       char ch_src_str[100];
  395:       char ch_grp_str[100];
  396: 
  397:       pim_inet4_dump("<ch_src?>", ch->source_addr,
  398: 		     ch_src_str, sizeof(ch_src_str));
  399:       pim_inet4_dump("<ch_grp?>", ch->group_addr,
  400: 		     ch_grp_str, sizeof(ch_grp_str));
  401: 
  402:       vty_out(vty, "%-9s %-15s %-15s %-15s %-10s%s",
  403: 	      ifp->name,
  404: 	      inet_ntoa(ifaddr),
  405: 	      ch_src_str,
  406: 	      ch_grp_str,
  407: 	      ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO ?
  408: 	      "NOINFO" : "INCLUDE",
  409: 	      VTY_NEWLINE);
  410:     } /* scan interface channels */
  411:   } /* scan interfaces */
  412: 
  413: }
  414: 
  415: static void igmp_show_interfaces(struct vty *vty)
  416: {
  417:   struct listnode  *node;
  418:   struct interface *ifp;
  419:   time_t            now;
  420:   
  421:   now = pim_time_monotonic_sec();
  422: 
  423:   vty_out(vty,
  424: 	  "Interface Address         ifIndex Socket Uptime   Multi Broad MLoop AllMu Prmsc Del%s",
  425: 	  VTY_NEWLINE);
  426: 
  427:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  428:     struct pim_interface *pim_ifp;
  429:     struct listnode *sock_node;
  430:     struct igmp_sock *igmp;
  431: 
  432:     pim_ifp = ifp->info;
  433:     
  434:     if (!pim_ifp)
  435:       continue;
  436: 
  437:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
  438:       char uptime[10];
  439:       int mloop;
  440: 
  441:       pim_time_uptime(uptime, sizeof(uptime), now - igmp->sock_creation);
  442: 
  443:       mloop = pim_socket_mcastloop_get(igmp->fd);
  444:       
  445:       vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
  446: 	      ifp->name,
  447: 	      inet_ntoa(igmp->ifaddr),
  448: 	      ifp->ifindex,
  449: 	      igmp->fd,
  450: 	      uptime,
  451: 	      if_is_multicast(ifp) ? "yes" : "no",
  452: 	      if_is_broadcast(ifp) ? "yes" : "no",
  453: 	      (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
  454: 	      (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
  455: 	      (ifp->flags & IFF_PROMISC) ? "yes" : "no",
  456: 	      PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
  457: 	      VTY_NEWLINE);
  458:     }
  459:   }
  460: }
  461: 
  462: static void igmp_show_interface_join(struct vty *vty)
  463: {
  464:   struct listnode  *node;
  465:   struct interface *ifp;
  466:   time_t            now;
  467:   
  468:   now = pim_time_monotonic_sec();
  469: 
  470:   vty_out(vty,
  471: 	  "Interface Address         Source          Group           Socket Uptime  %s",
  472: 	  VTY_NEWLINE);
  473: 
  474:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  475:     struct pim_interface *pim_ifp;
  476:     struct listnode *join_node;
  477:     struct igmp_join *ij;
  478:     struct in_addr pri_addr;
  479:     char pri_addr_str[100];
  480: 
  481:     pim_ifp = ifp->info;
  482:     
  483:     if (!pim_ifp)
  484:       continue;
  485: 
  486:     if (!pim_ifp->igmp_join_list)
  487:       continue;
  488: 
  489:     pri_addr = pim_find_primary_addr(ifp);
  490:     pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
  491: 
  492:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_join_list, join_node, ij)) {
  493:       char group_str[100];
  494:       char source_str[100];
  495:       char uptime[10];
  496: 
  497:       pim_time_uptime(uptime, sizeof(uptime), now - ij->sock_creation);
  498:       pim_inet4_dump("<grp?>", ij->group_addr, group_str, sizeof(group_str));
  499:       pim_inet4_dump("<src?>", ij->source_addr, source_str, sizeof(source_str));
  500:       
  501:       vty_out(vty, "%-9s %-15s %-15s %-15s %6d %8s%s",
  502: 	      ifp->name,
  503: 	      pri_addr_str,
  504: 	      source_str,
  505: 	      group_str,
  506: 	      ij->sock_fd,
  507: 	      uptime,
  508: 	      VTY_NEWLINE);
  509:     } /* for (pim_ifp->igmp_join_list) */
  510: 
  511:   } /* for (iflist) */
  512: 
  513: }
  514: 
  515: static void show_interface_address(struct vty *vty)
  516: {
  517:   struct listnode  *ifpnode;
  518:   struct interface *ifp;
  519:   
  520:   vty_out(vty,
  521: 	  "Interface Primary         Secondary      %s",
  522: 	  VTY_NEWLINE);
  523: 
  524:   for (ALL_LIST_ELEMENTS_RO(iflist, ifpnode, ifp)) {
  525:     struct listnode  *ifcnode;
  526:     struct connected *ifc;
  527:     struct in_addr    pri_addr;
  528:     char pri_addr_str[100];
  529: 
  530:     pri_addr = pim_find_primary_addr(ifp);
  531: 
  532:     pim_inet4_dump("<pri?>", pri_addr, pri_addr_str, sizeof(pri_addr_str));
  533:     
  534:     for (ALL_LIST_ELEMENTS_RO(ifp->connected, ifcnode, ifc)) {
  535:       char sec_addr_str[100];
  536:       struct prefix *p = ifc->address;
  537: 
  538:       if (p->family != AF_INET)
  539: 	continue;
  540: 
  541:       if (p->u.prefix4.s_addr == pri_addr.s_addr) {
  542: 	sec_addr_str[0] = '\0';
  543:       }
  544:       else {
  545: 	pim_inet4_dump("<sec?>", p->u.prefix4, sec_addr_str, sizeof(sec_addr_str));
  546:       }
  547:     
  548:       vty_out(vty, "%-9s %-15s %-15s%s",
  549: 	      ifp->name,
  550: 	      pri_addr_str,
  551: 	      sec_addr_str,
  552: 	      VTY_NEWLINE);
  553:     }
  554:   }
  555: }
  556: 
  557: static void pim_show_dr(struct vty *vty)
  558: {
  559:   struct listnode  *node;
  560:   struct interface *ifp;
  561:   time_t            now;
  562:   
  563:   now = pim_time_monotonic_sec();
  564: 
  565:   vty_out(vty,
  566: 	  "NonPri: Number of neighbors missing DR Priority hello option%s"
  567: 	  "DrPri: Designated Router Priority sent%s%s",
  568: 	  VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  569:   
  570:   vty_out(vty, "Interface Address         DR              Uptime   Elections Changes NonPri      DrPri%s", VTY_NEWLINE);
  571: 
  572:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  573:     struct pim_interface *pim_ifp;
  574:     struct in_addr ifaddr;
  575:     char dr_str[100];
  576:     char dr_uptime[10];
  577: 
  578:     pim_ifp = ifp->info;
  579:     
  580:     if (!pim_ifp)
  581:       continue;
  582: 
  583:     if (pim_ifp->pim_sock_fd < 0)
  584:       continue;
  585: 
  586:     ifaddr = pim_ifp->primary_address;
  587: 
  588:     pim_time_uptime_begin(dr_uptime, sizeof(dr_uptime),
  589: 			  now, pim_ifp->pim_dr_election_last);
  590: 
  591:     pim_inet4_dump("<dr?>", pim_ifp->pim_dr_addr,
  592: 		   dr_str, sizeof(dr_str));
  593: 
  594:     vty_out(vty, "%-9s %-15s %-15s %8s %9d %7d %6d %10d%s",
  595: 	    ifp->name,
  596: 	    inet_ntoa(ifaddr),
  597: 	    dr_str,
  598: 	    dr_uptime,
  599: 	    pim_ifp->pim_dr_election_count,
  600: 	    pim_ifp->pim_dr_election_changes,
  601: 	    pim_ifp->pim_dr_num_nondrpri_neighbors,
  602: 	    pim_ifp->pim_dr_priority,
  603: 	    VTY_NEWLINE);
  604:   }
  605: }
  606: 
  607: static void pim_show_hello(struct vty *vty)
  608: {
  609:   struct listnode  *node;
  610:   struct interface *ifp;
  611:   time_t            now;
  612:   
  613:   now = pim_time_monotonic_sec();
  614:   
  615:   vty_out(vty, "Interface Address         Period Timer StatStart Recv Rfail Send Sfail%s", VTY_NEWLINE);
  616: 
  617:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  618:     struct pim_interface *pim_ifp;
  619:     struct in_addr ifaddr;
  620:     char hello_period[10];
  621:     char hello_timer[10];
  622:     char stat_uptime[10];
  623: 
  624:     pim_ifp = ifp->info;
  625:     
  626:     if (!pim_ifp)
  627:       continue;
  628: 
  629:     if (pim_ifp->pim_sock_fd < 0)
  630:       continue;
  631: 
  632:     ifaddr = pim_ifp->primary_address;
  633: 
  634:     pim_time_timer_to_mmss(hello_timer, sizeof(hello_timer), pim_ifp->t_pim_hello_timer);
  635:     pim_time_mmss(hello_period, sizeof(hello_period), pim_ifp->pim_hello_period);
  636:     pim_time_uptime(stat_uptime, sizeof(stat_uptime), now - pim_ifp->pim_ifstat_start);
  637: 
  638:     vty_out(vty, "%-9s %-15s %6s %5s %9s %4u %5u %4u %5u%s",
  639: 	    ifp->name,
  640: 	    inet_ntoa(ifaddr),
  641: 	    hello_period,
  642: 	    hello_timer,
  643: 	    stat_uptime,
  644: 	    pim_ifp->pim_ifstat_hello_recv,
  645: 	    pim_ifp->pim_ifstat_hello_recvfail,
  646: 	    pim_ifp->pim_ifstat_hello_sent,
  647: 	    pim_ifp->pim_ifstat_hello_sendfail,
  648: 	    VTY_NEWLINE);
  649:   }
  650: }
  651: 
  652: static void pim_show_interfaces(struct vty *vty)
  653: {
  654:   struct listnode  *node;
  655:   struct interface *ifp;
  656:   time_t            now;
  657:   
  658:   now = pim_time_monotonic_sec();
  659: 
  660:   vty_out(vty, "Interface Address         ifIndex Socket Uptime   Multi Broad MLoop AllMu Prmsc Del%s", VTY_NEWLINE);
  661: 
  662:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  663:     struct pim_interface *pim_ifp;
  664:     struct in_addr ifaddr;
  665:     char uptime[10];
  666:     int mloop;
  667: 
  668:     pim_ifp = ifp->info;
  669:     
  670:     if (!pim_ifp)
  671:       continue;
  672: 
  673:     if (pim_ifp->pim_sock_fd < 0)
  674:       continue;
  675: 
  676:     ifaddr = pim_ifp->primary_address;
  677: 
  678:     pim_time_uptime(uptime, sizeof(uptime), now - pim_ifp->pim_sock_creation);
  679: 
  680:     mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
  681:       
  682:     vty_out(vty, "%-9s %-15s %7d %6d %8s %5s %5s %5s %5s %5s %3s%s",
  683: 	    ifp->name,
  684: 	    inet_ntoa(ifaddr),
  685: 	    ifp->ifindex,
  686: 	    pim_ifp->pim_sock_fd,
  687: 	    uptime,
  688: 	    if_is_multicast(ifp) ? "yes" : "no",
  689: 	    if_is_broadcast(ifp) ? "yes" : "no",
  690: 	    (mloop < 0) ? "?" : (mloop ? "yes" : "no"),
  691: 	    (ifp->flags & IFF_ALLMULTI) ? "yes" : "no",
  692: 	    (ifp->flags & IFF_PROMISC) ? "yes" : "no",
  693: 	    PIM_IF_IS_DELETED(ifp) ? "yes" : "no",
  694: 	    VTY_NEWLINE);
  695:   }
  696: }
  697: 
  698: static void pim_show_join(struct vty *vty)
  699: {
  700:   struct listnode  *ifnode;
  701:   struct interface *ifp;
  702:   time_t            now;
  703:   
  704:   now = pim_time_monotonic_sec();
  705: 
  706:   vty_out(vty,
  707: 	  "Interface Address         Source          Group           State  Uptime   Expire Prune%s",
  708: 	  VTY_NEWLINE);
  709: 
  710:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
  711:     struct pim_interface *pim_ifp;
  712:     struct in_addr ifaddr;
  713:     struct listnode *ch_node;
  714:     struct pim_ifchannel *ch;
  715: 
  716:     pim_ifp = ifp->info;
  717:     
  718:     if (!pim_ifp)
  719:       continue;
  720: 
  721:     ifaddr = pim_ifp->primary_address;
  722: 
  723:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
  724:       char ch_src_str[100];
  725:       char ch_grp_str[100];
  726:       char uptime[10];
  727:       char expire[10];
  728:       char prune[10];
  729: 
  730:       pim_inet4_dump("<ch_src?>", ch->source_addr,
  731: 		     ch_src_str, sizeof(ch_src_str));
  732:       pim_inet4_dump("<ch_grp?>", ch->group_addr,
  733: 		     ch_grp_str, sizeof(ch_grp_str));
  734: 
  735:       pim_time_uptime_begin(uptime, sizeof(uptime), now, ch->ifjoin_creation);
  736:       pim_time_timer_to_mmss(expire, sizeof(expire),
  737: 			     ch->t_ifjoin_expiry_timer);
  738:       pim_time_timer_to_mmss(prune, sizeof(prune),
  739: 			     ch->t_ifjoin_prune_pending_timer);
  740: 
  741:       vty_out(vty, "%-9s %-15s %-15s %-15s %-6s %8s %-6s %5s%s",
  742: 	      ifp->name,
  743: 	      inet_ntoa(ifaddr),
  744: 	      ch_src_str,
  745: 	      ch_grp_str,
  746: 	      pim_ifchannel_ifjoin_name(ch->ifjoin_state),
  747: 	      uptime,
  748: 	      expire,
  749: 	      prune,
  750: 	      VTY_NEWLINE);
  751:     } /* scan interface channels */
  752:   } /* scan interfaces */
  753: 
  754: }
  755: 
  756: static void pim_show_neighbors(struct vty *vty)
  757: {
  758:   struct listnode  *node;
  759:   struct interface *ifp;
  760:   time_t            now;
  761:   
  762:   now = pim_time_monotonic_sec();
  763: 
  764:   vty_out(vty,
  765: 	  "Recv flags: H=holdtime L=lan_prune_delay P=dr_priority G=generation_id A=address_list%s"
  766: 	  "            T=can_disable_join_suppression%s%s",
  767: 	  VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  768: 
  769:   vty_out(vty, "Interface Address         Neighbor        Uptime   Timer Holdt DrPri GenId    Recv  %s", VTY_NEWLINE);
  770: 
  771:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  772:     struct pim_interface *pim_ifp;
  773:     struct in_addr ifaddr;
  774:     struct listnode *neighnode;
  775:     struct pim_neighbor *neigh;
  776: 
  777:     pim_ifp = ifp->info;
  778:     
  779:     if (!pim_ifp)
  780:       continue;
  781: 
  782:     if (pim_ifp->pim_sock_fd < 0)
  783:       continue;
  784: 
  785:     ifaddr = pim_ifp->primary_address;
  786: 
  787:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
  788:       char uptime[10];
  789:       char holdtime[10];
  790:       char expire[10];
  791:       char neigh_src_str[100];
  792:       char recv[7];
  793: 
  794:       pim_inet4_dump("<src?>", neigh->source_addr,
  795: 		     neigh_src_str, sizeof(neigh_src_str));
  796:       pim_time_uptime(uptime, sizeof(uptime), now - neigh->creation);
  797:       pim_time_mmss(holdtime, sizeof(holdtime), neigh->holdtime);
  798:       pim_time_timer_to_mmss(expire, sizeof(expire), neigh->t_expire_timer);
  799: 
  800:       recv[0] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_HOLDTIME)                     ? 'H' : ' ';
  801:       recv[1] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY)              ? 'L' : ' ';
  802:       recv[2] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY)                  ? 'P' : ' ';
  803:       recv[3] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID)                ? 'G' : ' ';
  804:       recv[4] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_ADDRESS_LIST)                 ? 'A' : ' ';
  805:       recv[5] = PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION) ? 'T' : ' ';
  806:       recv[6] = '\0';
  807: 
  808:       vty_out(vty, "%-9s %-15s %-15s %8s %5s %5s %5u %08x %6s%s",
  809: 	      ifp->name,
  810: 	      inet_ntoa(ifaddr),
  811: 	      neigh_src_str,
  812: 	      uptime,
  813: 	      expire,
  814: 	      holdtime,
  815: 	      neigh->dr_priority,
  816: 	      neigh->generation_id,
  817: 	      recv,
  818: 	      VTY_NEWLINE);
  819:     }
  820: 
  821: 
  822:   }
  823: }
  824: 
  825: static void pim_show_lan_prune_delay(struct vty *vty)
  826: {
  827:   struct listnode  *node;
  828:   struct interface *ifp;
  829: 
  830:   vty_out(vty,
  831: 	  "PrDly=propagation_delay (msec)           OvInt=override_interval (msec)%s"
  832: 	  "HiDly=highest_propagation_delay (msec)   HiInt=highest_override_interval (msec)%s"
  833: 	  "NoDly=number_of_non_lan_delay_neighbors%s"
  834: 	  "T=t_bit LPD=lan_prune_delay_hello_option%s%s",
  835: 	  VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  836: 
  837:   vty_out(vty, "Interface Address         PrDly OvInt NoDly HiDly HiInt T | Neighbor        LPD PrDly OvInt T%s", VTY_NEWLINE);
  838: 
  839:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  840:     struct pim_interface *pim_ifp;
  841:     struct in_addr ifaddr;
  842:     struct listnode *neighnode;
  843:     struct pim_neighbor *neigh;
  844: 
  845:     pim_ifp = ifp->info;
  846:     
  847:     if (!pim_ifp)
  848:       continue;
  849: 
  850:     if (pim_ifp->pim_sock_fd < 0)
  851:       continue;
  852: 
  853:     ifaddr = pim_ifp->primary_address;
  854: 
  855:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
  856:       char neigh_src_str[100];
  857: 
  858:       pim_inet4_dump("<src?>", neigh->source_addr,
  859: 		     neigh_src_str, sizeof(neigh_src_str));
  860: 
  861:       vty_out(vty, "%-9s %-15s %5u %5u %5u %5u %5u %1u | %-15s %-3s %5u %5u %1u%s",
  862: 	      ifp->name,
  863: 	      inet_ntoa(ifaddr),
  864: 	      pim_ifp->pim_propagation_delay_msec,
  865: 	      pim_ifp->pim_override_interval_msec,
  866: 	      pim_ifp->pim_number_of_nonlandelay_neighbors,
  867: 	      pim_ifp->pim_neighbors_highest_propagation_delay_msec,
  868: 	      pim_ifp->pim_neighbors_highest_override_interval_msec,
  869: 	      PIM_FORCE_BOOLEAN(PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options)),
  870: 	      neigh_src_str,
  871: 	      PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY) ? "yes" : "no",
  872: 	      neigh->propagation_delay_msec,
  873: 	      neigh->override_interval_msec,
  874: 	      PIM_FORCE_BOOLEAN(PIM_OPTION_IS_SET(neigh->hello_options,
  875: 						  PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION)),
  876: 	      VTY_NEWLINE);
  877:     }
  878: 
  879:   }
  880: }
  881: 
  882: static void pim_show_jp_override_interval(struct vty *vty)
  883: {
  884:   struct listnode  *node;
  885:   struct interface *ifp;
  886: 
  887:   vty_out(vty,
  888: 	  "EffPDelay=effective_propagation_delay (msec)%s"
  889: 	  "EffOvrInt=override_interval (msec)%s"
  890: 	  "JPOvrInt=jp_override_interval (msec)%s%s",
  891: 	  VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  892: 
  893:   vty_out(vty, "Interface Address         LAN_Delay EffPDelay EffOvrInt JPOvrInt%s", VTY_NEWLINE);
  894: 
  895:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  896:     struct pim_interface *pim_ifp;
  897:     struct in_addr ifaddr;
  898: 
  899:     pim_ifp = ifp->info;
  900:     
  901:     if (!pim_ifp)
  902:       continue;
  903: 
  904:     if (pim_ifp->pim_sock_fd < 0)
  905:       continue;
  906: 
  907:     ifaddr = pim_ifp->primary_address;
  908: 
  909:     vty_out(vty, "%-9s %-15s %-9s %9u %9u %8u%s",
  910: 	    ifp->name,
  911: 	    inet_ntoa(ifaddr),
  912: 	    pim_if_lan_delay_enabled(ifp) ? "enabled" : "disabled",
  913: 	    pim_if_effective_propagation_delay_msec(ifp),
  914: 	    pim_if_effective_override_interval_msec(ifp),
  915: 	    pim_if_jp_override_interval_msec(ifp),
  916: 	    VTY_NEWLINE);
  917:   }
  918: }
  919: 
  920: static void pim_show_neighbors_secondary(struct vty *vty)
  921: {
  922:   struct listnode  *node;
  923:   struct interface *ifp;
  924: 
  925:   vty_out(vty, "Interface Address         Neighbor        Secondary      %s", VTY_NEWLINE);
  926: 
  927:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
  928:     struct pim_interface *pim_ifp;
  929:     struct in_addr ifaddr;
  930:     struct listnode *neighnode;
  931:     struct pim_neighbor *neigh;
  932: 
  933:     pim_ifp = ifp->info;
  934:     
  935:     if (!pim_ifp)
  936:       continue;
  937: 
  938:     if (pim_ifp->pim_sock_fd < 0)
  939:       continue;
  940: 
  941:     ifaddr = pim_ifp->primary_address;
  942: 
  943:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {
  944:       char neigh_src_str[100];
  945:       struct listnode *prefix_node;
  946:       struct prefix *p;
  947: 
  948:       if (!neigh->prefix_list)
  949: 	continue;
  950: 
  951:       pim_inet4_dump("<src?>", neigh->source_addr,
  952: 		     neigh_src_str, sizeof(neigh_src_str));
  953: 
  954:       for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
  955: 	char neigh_sec_str[100];
  956: 
  957: 	if (p->family != AF_INET)
  958: 	  continue;
  959: 
  960: 	pim_inet4_dump("<src?>", p->u.prefix4,
  961: 		       neigh_sec_str, sizeof(neigh_sec_str));
  962: 
  963: 	vty_out(vty, "%-9s %-15s %-15s %-15s%s",
  964: 		ifp->name,
  965: 		inet_ntoa(ifaddr),
  966: 		neigh_src_str,
  967: 		neigh_sec_str,
  968: 		VTY_NEWLINE);
  969:       }
  970:     }
  971:   }
  972: }
  973: 
  974: static void pim_show_upstream(struct vty *vty)
  975: {
  976:   struct listnode     *upnode;
  977:   struct pim_upstream *up;
  978:   time_t               now;
  979: 
  980:   now = pim_time_monotonic_sec();
  981: 
  982:   vty_out(vty, "Source          Group           State Uptime   JoinTimer RefCnt%s", VTY_NEWLINE);
  983: 
  984:   for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
  985:       char src_str[100];
  986:       char grp_str[100];
  987:       char uptime[10];
  988:       char join_timer[10];
  989: 
  990:       pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
  991:       pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
  992:       pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
  993:       pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer), up->t_join_timer);
  994: 
  995:       vty_out(vty, "%-15s %-15s %-5s %-8s %-9s %6d%s",
  996: 	      src_str,
  997: 	      grp_str,
  998: 	      up->join_state == PIM_UPSTREAM_JOINED ? "Jnd" : "NtJnd",
  999: 	      uptime,
 1000: 	      join_timer,
 1001: 	      up->ref_count,
 1002: 	      VTY_NEWLINE);
 1003:   }
 1004: }
 1005: 
 1006: static void pim_show_join_desired(struct vty *vty)
 1007: {
 1008:   struct listnode      *ifnode;
 1009:   struct listnode      *chnode;
 1010:   struct interface     *ifp;
 1011:   struct pim_interface *pim_ifp;
 1012:   struct pim_ifchannel *ch;
 1013:   char src_str[100];
 1014:   char grp_str[100];
 1015: 
 1016:   vty_out(vty,
 1017: 	  "Interface Source          Group           LostAssert Joins PimInclude JoinDesired EvalJD%s",
 1018: 	  VTY_NEWLINE);
 1019: 
 1020:   /* scan all interfaces */
 1021:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
 1022:     pim_ifp = ifp->info;
 1023:     if (!pim_ifp)
 1024:       continue;
 1025: 
 1026:     /* scan per-interface (S,G) state */
 1027:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, chnode, ch)) {
 1028:       struct pim_upstream *up = ch->upstream;
 1029: 
 1030:       pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
 1031:       pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
 1032: 
 1033:       vty_out(vty, "%-9s %-15s %-15s %-10s %-5s %-10s %-11s %-6s%s",
 1034: 	      ifp->name,
 1035: 	      src_str,
 1036: 	      grp_str,
 1037: 	      pim_macro_ch_lost_assert(ch) ? "yes" : "no",
 1038: 	      pim_macro_chisin_joins(ch) ? "yes" : "no",
 1039: 	      pim_macro_chisin_pim_include(ch) ? "yes" : "no",
 1040: 	      PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags) ? "yes" : "no",
 1041: 	      pim_upstream_evaluate_join_desired(up) ? "yes" : "no",
 1042: 	      VTY_NEWLINE);
 1043:     }
 1044:   }
 1045: }
 1046: 
 1047: static void pim_show_upstream_rpf(struct vty *vty)
 1048: {
 1049:   struct listnode     *upnode;
 1050:   struct pim_upstream *up;
 1051: 
 1052:   vty_out(vty,
 1053: 	  "Source          Group           RpfIface RibNextHop      RpfAddress     %s",
 1054: 	  VTY_NEWLINE);
 1055: 
 1056:   for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, upnode, up)) {
 1057:     char src_str[100];
 1058:     char grp_str[100];
 1059:     char rpf_nexthop_str[100];
 1060:     char rpf_addr_str[100];
 1061:     struct pim_rpf *rpf;
 1062:     const char *rpf_ifname;
 1063:     
 1064:     rpf = &up->rpf;
 1065:     
 1066:     pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
 1067:     pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
 1068:     pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rpf_nexthop_str, sizeof(rpf_nexthop_str));
 1069:     pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
 1070:     
 1071:     rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
 1072:     
 1073:     vty_out(vty, "%-15s %-15s %-8s %-15s %-15s%s",
 1074: 	    src_str,
 1075: 	    grp_str,
 1076: 	    rpf_ifname,
 1077: 	    rpf_nexthop_str,
 1078: 	    rpf_addr_str,
 1079: 	    VTY_NEWLINE);
 1080:   }
 1081: }
 1082: 
 1083: static void show_rpf_refresh_stats(struct vty *vty, time_t now)
 1084: {
 1085:   char refresh_uptime[10];
 1086: 
 1087:   pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, qpim_rpf_cache_refresh_last);
 1088: 
 1089:   vty_out(vty, 
 1090: 	  "RPF Cache Refresh Delay:    %ld msecs%s"
 1091: 	  "RPF Cache Refresh Timer:    %ld msecs%s"
 1092: 	  "RPF Cache Refresh Requests: %lld%s"
 1093: 	  "RPF Cache Refresh Events:   %lld%s"
 1094: 	  "RPF Cache Refresh Last:     %s%s",
 1095: 	  qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE,
 1096: 	  pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE,
 1097: 	  (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE,
 1098: 	  (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE,
 1099: 	  refresh_uptime, VTY_NEWLINE);
 1100: }
 1101: 
 1102: static void show_scan_oil_stats(struct vty *vty, time_t now)
 1103: {
 1104:   char uptime_scan_oil[10];
 1105:   char uptime_mroute_add[10];
 1106:   char uptime_mroute_del[10];
 1107: 
 1108:   pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now, qpim_scan_oil_last);
 1109:   pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now, qpim_mroute_add_last);
 1110:   pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now, qpim_mroute_del_last);
 1111: 
 1112:   vty_out(vty,
 1113:           "Scan OIL - Last: %s  Events: %lld%s"
 1114:           "MFC Add  - Last: %s  Events: %lld%s"
 1115:           "MFC Del  - Last: %s  Events: %lld%s",
 1116:           uptime_scan_oil,   (long long) qpim_scan_oil_events,   VTY_NEWLINE,
 1117:           uptime_mroute_add, (long long) qpim_mroute_add_events, VTY_NEWLINE,
 1118:           uptime_mroute_del, (long long) qpim_mroute_del_events, VTY_NEWLINE);
 1119: }
 1120: 
 1121: static void pim_show_rpf(struct vty *vty)
 1122: {
 1123:   struct listnode     *up_node;
 1124:   struct pim_upstream *up;
 1125:   time_t               now = pim_time_monotonic_sec();
 1126: 
 1127:   show_rpf_refresh_stats(vty, now);
 1128: 
 1129:   vty_out(vty, "%s", VTY_NEWLINE);
 1130: 
 1131:   vty_out(vty,
 1132: 	  "Source          Group           RpfIface RpfAddress      RibNextHop      Metric Pref%s",
 1133: 	  VTY_NEWLINE);
 1134: 
 1135:   for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
 1136:     char src_str[100];
 1137:     char grp_str[100];
 1138:     char rpf_addr_str[100];
 1139:     char rib_nexthop_str[100];
 1140:     const char *rpf_ifname;
 1141:     struct pim_rpf  *rpf = &up->rpf;
 1142:     
 1143:     pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
 1144:     pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
 1145:     pim_inet4_dump("<rpf?>", rpf->rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
 1146:     pim_inet4_dump("<nexthop?>", rpf->source_nexthop.mrib_nexthop_addr, rib_nexthop_str, sizeof(rib_nexthop_str));
 1147:     
 1148:     rpf_ifname = rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>";
 1149:     
 1150:     vty_out(vty, "%-15s %-15s %-8s %-15s %-15s %6d %4d%s",
 1151: 	    src_str,
 1152: 	    grp_str,
 1153: 	    rpf_ifname,
 1154: 	    rpf_addr_str,
 1155: 	    rib_nexthop_str,
 1156: 	    rpf->source_nexthop.mrib_route_metric,
 1157: 	    rpf->source_nexthop.mrib_metric_preference,
 1158: 	    VTY_NEWLINE);
 1159:   }
 1160: }
 1161: 
 1162: static void igmp_show_querier(struct vty *vty)
 1163: {
 1164:   struct listnode  *node;
 1165:   struct interface *ifp;
 1166: 
 1167:   vty_out(vty, "Interface Address         Querier StartCount Query-Timer Other-Timer%s", VTY_NEWLINE);
 1168: 
 1169:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
 1170:     struct pim_interface *pim_ifp = ifp->info;
 1171:     struct listnode  *sock_node;
 1172:     struct igmp_sock *igmp;
 1173:     
 1174:     if (!pim_ifp)
 1175:       continue;
 1176: 
 1177:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
 1178:       char query_hhmmss[10];
 1179:       char other_hhmmss[10];
 1180: 
 1181:       pim_time_timer_to_hhmmss(query_hhmmss, sizeof(query_hhmmss), igmp->t_igmp_query_timer);
 1182:       pim_time_timer_to_hhmmss(other_hhmmss, sizeof(other_hhmmss), igmp->t_other_querier_timer);
 1183: 
 1184:       vty_out(vty, "%-9s %-15s %-7s %10d %11s %11s%s",
 1185: 	      ifp->name,
 1186: 	      inet_ntoa(igmp->ifaddr),
 1187: 	      igmp->t_igmp_query_timer ? "THIS" : "OTHER",
 1188: 	      igmp->startup_query_count,
 1189: 	      query_hhmmss,
 1190: 	      other_hhmmss,
 1191: 	      VTY_NEWLINE);
 1192:     }
 1193:   }
 1194: }
 1195: 
 1196: static void igmp_show_groups(struct vty *vty)
 1197: {
 1198:   struct listnode  *ifnode;
 1199:   struct interface *ifp;
 1200:   time_t            now;
 1201: 
 1202:   now = pim_time_monotonic_sec();
 1203: 
 1204:   vty_out(vty, "Interface Address         Group           Mode Timer    Srcs V Uptime  %s", VTY_NEWLINE);
 1205: 
 1206:   /* scan interfaces */
 1207:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
 1208:     struct pim_interface *pim_ifp = ifp->info;
 1209:     struct listnode  *sock_node;
 1210:     struct igmp_sock *igmp;
 1211:     
 1212:     if (!pim_ifp)
 1213:       continue;
 1214:     
 1215:     /* scan igmp sockets */
 1216:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
 1217:       char ifaddr_str[100];
 1218:       struct listnode *grpnode;
 1219:       struct igmp_group *grp;
 1220: 
 1221:       pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
 1222: 
 1223:       /* scan igmp groups */
 1224:       for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
 1225: 	char group_str[100];
 1226: 	char hhmmss[10];
 1227: 	char uptime[10];
 1228: 
 1229: 	pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
 1230: 	pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss), grp->t_group_timer);
 1231: 	pim_time_uptime(uptime, sizeof(uptime), now - grp->group_creation);
 1232: 
 1233: 	vty_out(vty, "%-9s %-15s %-15s %4s %8s %4d %d %8s%s",
 1234: 		ifp->name,
 1235: 		ifaddr_str,
 1236: 		group_str,
 1237: 		grp->group_filtermode_isexcl ? "EXCL" : "INCL",
 1238: 		hhmmss,
 1239: 		grp->group_source_list ? listcount(grp->group_source_list) : 0,
 1240: 		igmp_group_compat_mode(igmp, grp),
 1241: 		uptime,
 1242: 		VTY_NEWLINE);
 1243: 
 1244:       } /* scan igmp groups */
 1245:     } /* scan igmp sockets */
 1246:   } /* scan interfaces */
 1247: }
 1248: 
 1249: static void igmp_show_group_retransmission(struct vty *vty)
 1250: {
 1251:   struct listnode  *ifnode;
 1252:   struct interface *ifp;
 1253: 
 1254:   vty_out(vty, "Interface Address         Group           RetTimer Counter RetSrcs%s", VTY_NEWLINE);
 1255: 
 1256:   /* scan interfaces */
 1257:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
 1258:     struct pim_interface *pim_ifp = ifp->info;
 1259:     struct listnode  *sock_node;
 1260:     struct igmp_sock *igmp;
 1261:     
 1262:     if (!pim_ifp)
 1263:       continue;
 1264:     
 1265:     /* scan igmp sockets */
 1266:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
 1267:       char ifaddr_str[100];
 1268:       struct listnode *grpnode;
 1269:       struct igmp_group *grp;
 1270: 
 1271:       pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
 1272: 
 1273:       /* scan igmp groups */
 1274:       for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
 1275: 	char group_str[100];
 1276: 	char grp_retr_mmss[10];
 1277: 	struct listnode    *src_node;
 1278: 	struct igmp_source *src;
 1279: 	int grp_retr_sources = 0;
 1280: 
 1281: 	pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
 1282: 	pim_time_timer_to_mmss(grp_retr_mmss, sizeof(grp_retr_mmss), grp->t_group_query_retransmit_timer);
 1283: 
 1284: 
 1285: 	/* count group sources with retransmission state */
 1286: 	for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
 1287: 	  if (src->source_query_retransmit_count > 0) {
 1288: 	    ++grp_retr_sources;
 1289: 	  }
 1290: 	}
 1291: 
 1292: 	vty_out(vty, "%-9s %-15s %-15s %-8s %7d %7d%s",
 1293: 		ifp->name,
 1294: 		ifaddr_str,
 1295: 		group_str,
 1296: 		grp_retr_mmss,
 1297: 		grp->group_specific_query_retransmit_count,
 1298: 		grp_retr_sources,
 1299: 		VTY_NEWLINE);
 1300: 
 1301:       } /* scan igmp groups */
 1302:     } /* scan igmp sockets */
 1303:   } /* scan interfaces */
 1304: }
 1305: 
 1306: static void igmp_show_parameters(struct vty *vty)
 1307: {
 1308:   struct listnode  *ifnode;
 1309:   struct interface *ifp;
 1310: 
 1311:   vty_out(vty,
 1312: 	  "QRV: Robustness Variable             SQI: Startup Query Interval%s"
 1313: 	  "QQI: Query Interval                  OQPI: Other Querier Present Interval%s"
 1314: 	  "QRI: Query Response Interval         LMQT: Last Member Query Time%s"
 1315: 	  "GMI: Group Membership Interval       OHPI: Older Host Present Interval%s%s",
 1316: 	  VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
 1317: 
 1318:   vty_out(vty,
 1319: 	  "Interface Address         QRV QQI QRI   GMI   SQI OQPI  LMQT  OHPI %s",
 1320: 	  VTY_NEWLINE);
 1321: 
 1322:   /* scan interfaces */
 1323:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
 1324:     struct pim_interface *pim_ifp = ifp->info;
 1325:     struct listnode  *sock_node;
 1326:     struct igmp_sock *igmp;
 1327:     
 1328:     if (!pim_ifp)
 1329:       continue;
 1330:     
 1331:     /* scan igmp sockets */
 1332:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
 1333:       char ifaddr_str[100];
 1334:       long gmi_dsec;  /* Group Membership Interval */
 1335:       long oqpi_dsec; /* Other Querier Present Interval */
 1336:       int  sqi;
 1337:       long lmqt_dsec;
 1338:       long ohpi_dsec;
 1339:       long qri_dsec;
 1340: 
 1341:       pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
 1342: 
 1343:       gmi_dsec = PIM_IGMP_GMI_MSEC(igmp->querier_robustness_variable,
 1344: 				   igmp->querier_query_interval,
 1345: 				   pim_ifp->igmp_query_max_response_time_dsec) / 100;
 1346: 
 1347:       sqi = PIM_IGMP_SQI(pim_ifp->igmp_default_query_interval);
 1348: 
 1349:       oqpi_dsec = PIM_IGMP_OQPI_MSEC(igmp->querier_robustness_variable,
 1350: 				     igmp->querier_query_interval,
 1351: 				     pim_ifp->igmp_query_max_response_time_dsec) / 100;
 1352: 
 1353:       lmqt_dsec = PIM_IGMP_LMQT_MSEC(pim_ifp->igmp_query_max_response_time_dsec,
 1354: 				     igmp->querier_robustness_variable) / 100;
 1355: 
 1356:       ohpi_dsec = PIM_IGMP_OHPI_DSEC(igmp->querier_robustness_variable,
 1357: 				     igmp->querier_query_interval,
 1358: 				     pim_ifp->igmp_query_max_response_time_dsec);
 1359: 
 1360:       qri_dsec = pim_ifp->igmp_query_max_response_time_dsec;
 1361: 
 1362:       vty_out(vty,
 1363: 	      "%-9s %-15s %3d %3d %3ld.%ld %3ld.%ld %3d %3ld.%ld %3ld.%ld %3ld.%ld%s",
 1364: 	      ifp->name,
 1365: 	      ifaddr_str,
 1366: 	      igmp->querier_robustness_variable,
 1367: 	      igmp->querier_query_interval,
 1368: 	      qri_dsec / 10, qri_dsec % 10,
 1369: 	      gmi_dsec / 10, gmi_dsec % 10,
 1370: 	      sqi,
 1371: 	      oqpi_dsec / 10, oqpi_dsec % 10,
 1372: 	      lmqt_dsec / 10, lmqt_dsec % 10,
 1373: 	      ohpi_dsec / 10, ohpi_dsec % 10,
 1374: 	      VTY_NEWLINE);
 1375: 
 1376:     } /* scan igmp sockets */
 1377:   } /* scan interfaces */
 1378: }
 1379: 
 1380: static void igmp_show_sources(struct vty *vty)
 1381: {
 1382:   struct listnode  *ifnode;
 1383:   struct interface *ifp;
 1384:   time_t            now;
 1385: 
 1386:   now = pim_time_monotonic_sec();
 1387: 
 1388:   vty_out(vty, "Interface Address         Group           Source          Timer Fwd Uptime  %s", VTY_NEWLINE);
 1389: 
 1390:   /* scan interfaces */
 1391:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
 1392:     struct pim_interface *pim_ifp = ifp->info;
 1393:     struct listnode  *sock_node;
 1394:     struct igmp_sock *igmp;
 1395:     
 1396:     if (!pim_ifp)
 1397:       continue;
 1398:     
 1399:     /* scan igmp sockets */
 1400:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
 1401:       char ifaddr_str[100];
 1402:       struct listnode   *grpnode;
 1403:       struct igmp_group *grp;
 1404: 
 1405:       pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
 1406: 
 1407:       /* scan igmp groups */
 1408:       for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
 1409: 	char group_str[100];
 1410: 	struct listnode    *srcnode;
 1411: 	struct igmp_source *src;
 1412: 
 1413: 	pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
 1414: 	
 1415: 	/* scan group sources */
 1416: 	for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
 1417: 	  char source_str[100];
 1418: 	  char mmss[10];
 1419: 	  char uptime[10];
 1420: 
 1421: 	  pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
 1422: 
 1423: 	  pim_time_timer_to_mmss(mmss, sizeof(mmss), src->t_source_timer);
 1424: 
 1425: 	  pim_time_uptime(uptime, sizeof(uptime), now - src->source_creation);
 1426: 
 1427: 	  vty_out(vty, "%-9s %-15s %-15s %-15s %5s %3s %8s%s",
 1428: 		  ifp->name,
 1429: 		  ifaddr_str,
 1430: 		  group_str,
 1431: 		  source_str,
 1432: 		  mmss,
 1433: 		  IGMP_SOURCE_TEST_FORWARDING(src->source_flags) ? "Y" : "N",
 1434: 		  uptime,
 1435: 		  VTY_NEWLINE);
 1436: 	  
 1437: 	} /* scan group sources */
 1438:       } /* scan igmp groups */
 1439:     } /* scan igmp sockets */
 1440:   } /* scan interfaces */
 1441: }
 1442: 
 1443: static void igmp_show_source_retransmission(struct vty *vty)
 1444: {
 1445:   struct listnode  *ifnode;
 1446:   struct interface *ifp;
 1447: 
 1448:   vty_out(vty, "Interface Address         Group           Source          Counter%s", VTY_NEWLINE);
 1449: 
 1450:   /* scan interfaces */
 1451:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
 1452:     struct pim_interface *pim_ifp = ifp->info;
 1453:     struct listnode  *sock_node;
 1454:     struct igmp_sock *igmp;
 1455:     
 1456:     if (!pim_ifp)
 1457:       continue;
 1458:     
 1459:     /* scan igmp sockets */
 1460:     for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
 1461:       char ifaddr_str[100];
 1462:       struct listnode   *grpnode;
 1463:       struct igmp_group *grp;
 1464: 
 1465:       pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
 1466: 
 1467:       /* scan igmp groups */
 1468:       for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode, grp)) {
 1469: 	char group_str[100];
 1470: 	struct listnode    *srcnode;
 1471: 	struct igmp_source *src;
 1472: 
 1473: 	pim_inet4_dump("<group?>", grp->group_addr, group_str, sizeof(group_str));
 1474: 	
 1475: 	/* scan group sources */
 1476: 	for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode, src)) {
 1477: 	  char source_str[100];
 1478: 
 1479: 	  pim_inet4_dump("<source?>", src->source_addr, source_str, sizeof(source_str));
 1480: 
 1481: 	  vty_out(vty, "%-9s %-15s %-15s %-15s %7d%s",
 1482: 		  ifp->name,
 1483: 		  ifaddr_str,
 1484: 		  group_str,
 1485: 		  source_str,
 1486: 		  src->source_query_retransmit_count,
 1487: 		  VTY_NEWLINE);
 1488: 	  
 1489: 	} /* scan group sources */
 1490:       } /* scan igmp groups */
 1491:     } /* scan igmp sockets */
 1492:   } /* scan interfaces */
 1493: }
 1494: 
 1495: static void clear_igmp_interfaces()
 1496: {
 1497:   struct listnode  *ifnode;
 1498:   struct listnode  *ifnextnode;
 1499:   struct interface *ifp;
 1500: 
 1501:   for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
 1502:     pim_if_addr_del_all_igmp(ifp);
 1503:   }
 1504: 
 1505:   for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
 1506:     pim_if_addr_add_all(ifp);
 1507:   }
 1508: }
 1509: 
 1510: static void clear_pim_interfaces()
 1511: {
 1512:   struct listnode  *ifnode;
 1513:   struct listnode  *ifnextnode;
 1514:   struct interface *ifp;
 1515: 
 1516:   for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
 1517:     if (ifp->info) {
 1518:       pim_neighbor_delete_all(ifp, "interface cleared");
 1519:     }
 1520:   }
 1521: }
 1522: 
 1523: static void clear_interfaces()
 1524: {
 1525:   clear_igmp_interfaces();
 1526:   clear_pim_interfaces();
 1527: }
 1528: 
 1529: DEFUN (pim_interface,
 1530:        pim_interface_cmd,
 1531:        "interface IFNAME",
 1532:        "Select an interface to configure\n"
 1533:        "Interface's name\n")
 1534: {
 1535:   struct interface *ifp;
 1536:   const char *ifname = argv[0];
 1537:   size_t sl;
 1538: 
 1539:   sl = strlen(ifname);
 1540:   if (sl > INTERFACE_NAMSIZ) {
 1541:     vty_out(vty, "%% Interface name %s is invalid: length exceeds "
 1542: 	    "%d characters%s",
 1543: 	    ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
 1544:     return CMD_WARNING;
 1545:   }
 1546: 
 1547:   ifp = if_lookup_by_name_len(ifname, sl);
 1548:   if (!ifp) {
 1549:     vty_out(vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
 1550: 
 1551:     /* Returning here would prevent pimd from booting when there are
 1552:        interface commands in pimd.conf, since all interfaces are
 1553:        unknown at pimd boot time (the zebra daemon has not been
 1554:        contacted for interface discovery). */
 1555:     
 1556:     ifp = if_get_by_name_len(ifname, sl);
 1557:     if (!ifp) {
 1558:       vty_out(vty, "%% Could not create interface %s%s", ifname, VTY_NEWLINE);
 1559:       return CMD_WARNING;
 1560:     }
 1561:   }
 1562: 
 1563:   vty->index = ifp;
 1564:   vty->node = INTERFACE_NODE;
 1565: 
 1566:   return CMD_SUCCESS;
 1567: }
 1568: 
 1569: DEFUN (clear_ip_interfaces,
 1570:        clear_ip_interfaces_cmd,
 1571:        "clear ip interfaces",
 1572:        CLEAR_STR
 1573:        IP_STR
 1574:        "Reset interfaces\n")
 1575: {
 1576:   clear_interfaces();
 1577: 
 1578:   return CMD_SUCCESS;
 1579: }
 1580: 
 1581: DEFUN (clear_ip_igmp_interfaces,
 1582:        clear_ip_igmp_interfaces_cmd,
 1583:        "clear ip igmp interfaces",
 1584:        CLEAR_STR
 1585:        IP_STR
 1586:        CLEAR_IP_IGMP_STR
 1587:        "Reset IGMP interfaces\n")
 1588: {
 1589:   clear_igmp_interfaces();
 1590: 
 1591:   return CMD_SUCCESS;
 1592: }
 1593: 
 1594: static void mroute_add_all()
 1595: {
 1596:   struct listnode    *node;
 1597:   struct channel_oil *c_oil;
 1598: 
 1599:   for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
 1600:     if (pim_mroute_add(&c_oil->oil)) {
 1601:       /* just log warning */
 1602:       char source_str[100];
 1603:       char group_str[100];
 1604:       pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
 1605:       pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
 1606:       zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
 1607:                 __FILE__, __PRETTY_FUNCTION__,
 1608:                 source_str, group_str);
 1609:     }
 1610:   }
 1611: }
 1612: 
 1613: static void mroute_del_all()
 1614: {
 1615:   struct listnode    *node;
 1616:   struct channel_oil *c_oil;
 1617: 
 1618:   for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
 1619:     if (pim_mroute_del(&c_oil->oil)) {
 1620:       /* just log warning */
 1621:       char source_str[100];
 1622:       char group_str[100];
 1623:       pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
 1624:       pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
 1625:       zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
 1626:                 __FILE__, __PRETTY_FUNCTION__,
 1627:                 source_str, group_str);
 1628:     }
 1629:   }
 1630: }
 1631: 
 1632: static void static_mroute_add_all()
 1633: {
 1634:   struct listnode     *node;
 1635:   struct static_route *s_route;
 1636: 
 1637:   for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
 1638:     if (pim_mroute_add(&s_route->mc)) {
 1639:       /* just log warning */
 1640:       char source_str[100];
 1641:       char group_str[100];
 1642:       pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
 1643:       pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
 1644:       zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
 1645:       __FILE__, __PRETTY_FUNCTION__,
 1646:       source_str, group_str);
 1647:     }
 1648:   }
 1649: }
 1650: 
 1651: static void static_mroute_del_all()
 1652: {
 1653:    struct listnode     *node;
 1654:    struct static_route *s_route;
 1655: 
 1656:    for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
 1657:      if (pim_mroute_del(&s_route->mc)) {
 1658:        /* just log warning */
 1659:        char source_str[100];
 1660:        char group_str[100];
 1661:        pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
 1662:        pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
 1663:        zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
 1664:        __FILE__, __PRETTY_FUNCTION__,
 1665:        source_str, group_str);
 1666:      }
 1667:    }
 1668: }
 1669: 
 1670: DEFUN (clear_ip_mroute,
 1671:        clear_ip_mroute_cmd,
 1672:        "clear ip mroute",
 1673:        CLEAR_STR
 1674:        IP_STR
 1675:        "Reset multicast routes\n")
 1676: {
 1677:   mroute_del_all();
 1678:   mroute_add_all();
 1679: 
 1680:   return CMD_SUCCESS;
 1681: }
 1682: 
 1683: DEFUN (clear_ip_pim_interfaces,
 1684:        clear_ip_pim_interfaces_cmd,
 1685:        "clear ip pim interfaces",
 1686:        CLEAR_STR
 1687:        IP_STR
 1688:        CLEAR_IP_PIM_STR
 1689:        "Reset PIM interfaces\n")
 1690: {
 1691:   clear_pim_interfaces();
 1692: 
 1693:   return CMD_SUCCESS;
 1694: }
 1695: 
 1696: DEFUN (clear_ip_pim_oil,
 1697:        clear_ip_pim_oil_cmd,
 1698:        "clear ip pim oil",
 1699:        CLEAR_STR
 1700:        IP_STR
 1701:        CLEAR_IP_PIM_STR
 1702:        "Rescan PIM OIL (output interface list)\n")
 1703: {
 1704:   pim_scan_oil();
 1705: 
 1706:   return CMD_SUCCESS;
 1707: }
 1708: 
 1709: DEFUN (show_ip_igmp_interface,
 1710:        show_ip_igmp_interface_cmd,
 1711:        "show ip igmp interface",
 1712:        SHOW_STR
 1713:        IP_STR
 1714:        IGMP_STR
 1715:        "IGMP interface information\n")
 1716: {
 1717:   igmp_show_interfaces(vty);
 1718: 
 1719:   return CMD_SUCCESS;
 1720: }
 1721: 
 1722: DEFUN (show_ip_igmp_join,
 1723:        show_ip_igmp_join_cmd,
 1724:        "show ip igmp join",
 1725:        SHOW_STR
 1726:        IP_STR
 1727:        IGMP_STR
 1728:        "IGMP static join information\n")
 1729: {
 1730:   igmp_show_interface_join(vty);
 1731: 
 1732:   return CMD_SUCCESS;
 1733: }
 1734: 
 1735: DEFUN (show_ip_igmp_groups,
 1736:        show_ip_igmp_groups_cmd,
 1737:        "show ip igmp groups",
 1738:        SHOW_STR
 1739:        IP_STR
 1740:        IGMP_STR
 1741:        IGMP_GROUP_STR)
 1742: {
 1743:   igmp_show_groups(vty);
 1744: 
 1745:   return CMD_SUCCESS;
 1746: }
 1747: 
 1748: DEFUN (show_ip_igmp_groups_retransmissions,
 1749:        show_ip_igmp_groups_retransmissions_cmd,
 1750:        "show ip igmp groups retransmissions",
 1751:        SHOW_STR
 1752:        IP_STR
 1753:        IGMP_STR
 1754:        IGMP_GROUP_STR
 1755:        "IGMP group retransmissions\n")
 1756: {
 1757:   igmp_show_group_retransmission(vty);
 1758: 
 1759:   return CMD_SUCCESS;
 1760: }
 1761: 
 1762: DEFUN (show_ip_igmp_parameters,
 1763:        show_ip_igmp_parameters_cmd,
 1764:        "show ip igmp parameters",
 1765:        SHOW_STR
 1766:        IP_STR
 1767:        IGMP_STR
 1768:        "IGMP parameters information\n")
 1769: {
 1770:   igmp_show_parameters(vty);
 1771: 
 1772:   return CMD_SUCCESS;
 1773: }
 1774: 
 1775: DEFUN (show_ip_igmp_sources,
 1776:        show_ip_igmp_sources_cmd,
 1777:        "show ip igmp sources",
 1778:        SHOW_STR
 1779:        IP_STR
 1780:        IGMP_STR
 1781:        IGMP_SOURCE_STR)
 1782: {
 1783:   igmp_show_sources(vty);
 1784: 
 1785:   return CMD_SUCCESS;
 1786: }
 1787: 
 1788: DEFUN (show_ip_igmp_sources_retransmissions,
 1789:        show_ip_igmp_sources_retransmissions_cmd,
 1790:        "show ip igmp sources retransmissions",
 1791:        SHOW_STR
 1792:        IP_STR
 1793:        IGMP_STR
 1794:        IGMP_SOURCE_STR
 1795:        "IGMP source retransmissions\n")
 1796: {
 1797:   igmp_show_source_retransmission(vty);
 1798: 
 1799:   return CMD_SUCCESS;
 1800: }
 1801: 
 1802: DEFUN (show_ip_igmp_querier,
 1803:        show_ip_igmp_querier_cmd,
 1804:        "show ip igmp querier",
 1805:        SHOW_STR
 1806:        IP_STR
 1807:        IGMP_STR
 1808:        "IGMP querier information\n")
 1809: {
 1810:   igmp_show_querier(vty);
 1811: 
 1812:   return CMD_SUCCESS;
 1813: }
 1814: 
 1815: DEFUN (show_ip_pim_address,
 1816:        show_ip_pim_address_cmd,
 1817:        "show ip pim address",
 1818:        SHOW_STR
 1819:        IP_STR
 1820:        PIM_STR
 1821:        "PIM interface address\n")
 1822: {
 1823:   show_interface_address(vty);
 1824: 
 1825:   return CMD_SUCCESS;
 1826: }
 1827: 
 1828: DEFUN (show_ip_pim_assert,
 1829:        show_ip_pim_assert_cmd,
 1830:        "show ip pim assert",
 1831:        SHOW_STR
 1832:        IP_STR
 1833:        PIM_STR
 1834:        "PIM interface assert\n")
 1835: {
 1836:   pim_show_assert(vty);
 1837: 
 1838:   return CMD_SUCCESS;
 1839: }
 1840: 
 1841: DEFUN (show_ip_pim_assert_internal,
 1842:        show_ip_pim_assert_internal_cmd,
 1843:        "show ip pim assert-internal",
 1844:        SHOW_STR
 1845:        IP_STR
 1846:        PIM_STR
 1847:        "PIM interface internal assert state\n")
 1848: {
 1849:   pim_show_assert_internal(vty);
 1850: 
 1851:   return CMD_SUCCESS;
 1852: }
 1853: 
 1854: DEFUN (show_ip_pim_assert_metric,
 1855:        show_ip_pim_assert_metric_cmd,
 1856:        "show ip pim assert-metric",
 1857:        SHOW_STR
 1858:        IP_STR
 1859:        PIM_STR
 1860:        "PIM interface assert metric\n")
 1861: {
 1862:   pim_show_assert_metric(vty);
 1863: 
 1864:   return CMD_SUCCESS;
 1865: }
 1866: 
 1867: DEFUN (show_ip_pim_assert_winner_metric,
 1868:        show_ip_pim_assert_winner_metric_cmd,
 1869:        "show ip pim assert-winner-metric",
 1870:        SHOW_STR
 1871:        IP_STR
 1872:        PIM_STR
 1873:        "PIM interface assert winner metric\n")
 1874: {
 1875:   pim_show_assert_winner_metric(vty);
 1876: 
 1877:   return CMD_SUCCESS;
 1878: }
 1879: 
 1880: DEFUN (show_ip_pim_dr,
 1881:        show_ip_pim_dr_cmd,
 1882:        "show ip pim designated-router",
 1883:        SHOW_STR
 1884:        IP_STR
 1885:        PIM_STR
 1886:        "PIM interface designated router\n")
 1887: {
 1888:   pim_show_dr(vty);
 1889: 
 1890:   return CMD_SUCCESS;
 1891: }
 1892: 
 1893: DEFUN (show_ip_pim_hello,
 1894:        show_ip_pim_hello_cmd,
 1895:        "show ip pim hello",
 1896:        SHOW_STR
 1897:        IP_STR
 1898:        PIM_STR
 1899:        "PIM interface hello information\n")
 1900: {
 1901:   pim_show_hello(vty);
 1902: 
 1903:   return CMD_SUCCESS;
 1904: }
 1905: 
 1906: DEFUN (show_ip_pim_interface,
 1907:        show_ip_pim_interface_cmd,
 1908:        "show ip pim interface",
 1909:        SHOW_STR
 1910:        IP_STR
 1911:        PIM_STR
 1912:        "PIM interface information\n")
 1913: {
 1914:   pim_show_interfaces(vty);
 1915: 
 1916:   return CMD_SUCCESS;
 1917: }
 1918: 
 1919: DEFUN (show_ip_pim_join,
 1920:        show_ip_pim_join_cmd,
 1921:        "show ip pim join",
 1922:        SHOW_STR
 1923:        IP_STR
 1924:        PIM_STR
 1925:        "PIM interface join information\n")
 1926: {
 1927:   pim_show_join(vty);
 1928: 
 1929:   return CMD_SUCCESS;
 1930: }
 1931: 
 1932: DEFUN (show_ip_pim_lan_prune_delay,
 1933:        show_ip_pim_lan_prune_delay_cmd,
 1934:        "show ip pim lan-prune-delay",
 1935:        SHOW_STR
 1936:        IP_STR
 1937:        PIM_STR
 1938:        "PIM neighbors LAN prune delay parameters\n")
 1939: {
 1940:   pim_show_lan_prune_delay(vty);
 1941: 
 1942:   return CMD_SUCCESS;
 1943: }
 1944: 
 1945: DEFUN (show_ip_pim_local_membership,
 1946:        show_ip_pim_local_membership_cmd,
 1947:        "show ip pim local-membership",
 1948:        SHOW_STR
 1949:        IP_STR
 1950:        PIM_STR
 1951:        "PIM interface local-membership\n")
 1952: {
 1953:   pim_show_membership(vty);
 1954: 
 1955:   return CMD_SUCCESS;
 1956: }
 1957: 
 1958: DEFUN (show_ip_pim_jp_override_interval,
 1959:        show_ip_pim_jp_override_interval_cmd,
 1960:        "show ip pim jp-override-interval",
 1961:        SHOW_STR
 1962:        IP_STR
 1963:        PIM_STR
 1964:        "PIM interface J/P override interval\n")
 1965: {
 1966:   pim_show_jp_override_interval(vty);
 1967: 
 1968:   return CMD_SUCCESS;
 1969: }
 1970: 
 1971: DEFUN (show_ip_pim_neighbor,
 1972:        show_ip_pim_neighbor_cmd,
 1973:        "show ip pim neighbor",
 1974:        SHOW_STR
 1975:        IP_STR
 1976:        PIM_STR
 1977:        "PIM neighbor information\n")
 1978: {
 1979:   pim_show_neighbors(vty);
 1980: 
 1981:   return CMD_SUCCESS;
 1982: }
 1983: 
 1984: DEFUN (show_ip_pim_secondary,
 1985:        show_ip_pim_secondary_cmd,
 1986:        "show ip pim secondary",
 1987:        SHOW_STR
 1988:        IP_STR
 1989:        PIM_STR
 1990:        "PIM neighbor addresses\n")
 1991: {
 1992:   pim_show_neighbors_secondary(vty);
 1993: 
 1994:   return CMD_SUCCESS;
 1995: }
 1996: 
 1997: DEFUN (show_ip_pim_upstream,
 1998:        show_ip_pim_upstream_cmd,
 1999:        "show ip pim upstream",
 2000:        SHOW_STR
 2001:        IP_STR
 2002:        PIM_STR
 2003:        "PIM upstream information\n")
 2004: {
 2005:   pim_show_upstream(vty);
 2006: 
 2007:   return CMD_SUCCESS;
 2008: }
 2009: 
 2010: DEFUN (show_ip_pim_upstream_join_desired,
 2011:        show_ip_pim_upstream_join_desired_cmd,
 2012:        "show ip pim upstream-join-desired",
 2013:        SHOW_STR
 2014:        IP_STR
 2015:        PIM_STR
 2016:        "PIM upstream join-desired\n")
 2017: {
 2018:   pim_show_join_desired(vty);
 2019: 
 2020:   return CMD_SUCCESS;
 2021: }
 2022: 
 2023: DEFUN (show_ip_pim_upstream_rpf,
 2024:        show_ip_pim_upstream_rpf_cmd,
 2025:        "show ip pim upstream-rpf",
 2026:        SHOW_STR
 2027:        IP_STR
 2028:        PIM_STR
 2029:        "PIM upstream source rpf\n")
 2030: {
 2031:   pim_show_upstream_rpf(vty);
 2032: 
 2033:   return CMD_SUCCESS;
 2034: }
 2035: 
 2036: DEFUN (show_ip_pim_rpf,
 2037:        show_ip_pim_rpf_cmd,
 2038:        "show ip pim rpf",
 2039:        SHOW_STR
 2040:        IP_STR
 2041:        PIM_STR
 2042:        "PIM cached source rpf information\n")
 2043: {
 2044:   pim_show_rpf(vty);
 2045: 
 2046:   return CMD_SUCCESS;
 2047: }
 2048: 
 2049: static void show_multicast_interfaces(struct vty *vty)
 2050: {
 2051:   struct listnode  *node;
 2052:   struct interface *ifp;
 2053: 
 2054:   vty_out(vty, "%s", VTY_NEWLINE);
 2055:   
 2056:   vty_out(vty, "Interface Address         ifi Vif  PktsIn PktsOut    BytesIn   BytesOut%s",
 2057: 	  VTY_NEWLINE);
 2058: 
 2059:   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
 2060:     struct pim_interface *pim_ifp;
 2061:     struct in_addr ifaddr;
 2062:     struct sioc_vif_req vreq;
 2063: 
 2064:     pim_ifp = ifp->info;
 2065:     
 2066:     if (!pim_ifp)
 2067:       continue;
 2068: 
 2069:     memset(&vreq, 0, sizeof(vreq));
 2070:     vreq.vifi = pim_ifp->mroute_vif_index;
 2071: 
 2072:     if (ioctl(qpim_mroute_socket_fd, SIOCGETVIFCNT, &vreq)) {
 2073:       zlog_warn("ioctl(SIOCGETVIFCNT=%lu) failure for interface %s vif_index=%d: errno=%d: %s%s",
 2074: 		(unsigned long)SIOCGETVIFCNT,
 2075: 		ifp->name,
 2076: 		pim_ifp->mroute_vif_index,
 2077: 		errno,
 2078: 		safe_strerror(errno),
 2079: 		VTY_NEWLINE);
 2080:     }
 2081: 
 2082:     ifaddr = pim_ifp->primary_address;
 2083: 
 2084:     vty_out(vty, "%-9s %-15s %3d %3d %7lu %7lu %10lu %10lu%s",
 2085: 	    ifp->name,
 2086: 	    inet_ntoa(ifaddr),
 2087: 	    ifp->ifindex,
 2088: 	    pim_ifp->mroute_vif_index,
 2089: 	    vreq.icount,
 2090: 	    vreq.ocount,
 2091: 	    vreq.ibytes,
 2092: 	    vreq.obytes,
 2093: 	    VTY_NEWLINE);
 2094:   }
 2095: }
 2096: 
 2097: DEFUN (show_ip_multicast,
 2098:        show_ip_multicast_cmd,
 2099:        "show ip multicast",
 2100:        SHOW_STR
 2101:        IP_STR
 2102:        "Multicast global information\n")
 2103: {
 2104:   time_t now = pim_time_monotonic_sec();
 2105: 
 2106:   if (PIM_MROUTE_IS_ENABLED) {
 2107:     char uptime[10];
 2108: 
 2109:     vty_out(vty, "Mroute socket descriptor: %d%s",
 2110: 	    qpim_mroute_socket_fd,
 2111: 	    VTY_NEWLINE);
 2112: 
 2113:     pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
 2114:     vty_out(vty, "Mroute socket uptime: %s%s",
 2115: 	    uptime,
 2116: 	    VTY_NEWLINE);
 2117:   }
 2118:   else {
 2119:     vty_out(vty, "Multicast disabled%s",
 2120: 	    VTY_NEWLINE);
 2121:   }
 2122: 
 2123:   vty_out(vty, "%s", VTY_NEWLINE);
 2124:   vty_out(vty, "Zclient update socket: ");
 2125:   if (qpim_zclient_update) {
 2126:     vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
 2127: 	    qpim_zclient_update->fail, VTY_NEWLINE);
 2128:   }
 2129:   else {
 2130:     vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
 2131:   }
 2132:   vty_out(vty, "Zclient lookup socket: ");
 2133:   if (qpim_zclient_lookup) {
 2134:     vty_out(vty, "%d failures=%d%s", qpim_zclient_lookup->sock,
 2135: 	    qpim_zclient_lookup->fail, VTY_NEWLINE);
 2136:   }
 2137:   else {
 2138:     vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
 2139:   }
 2140: 
 2141:   vty_out(vty, "%s", VTY_NEWLINE);
 2142:   vty_out(vty, "Current highest VifIndex: %d%s",
 2143: 	  qpim_mroute_oif_highest_vif_index,
 2144: 	  VTY_NEWLINE);
 2145:   vty_out(vty, "Maximum highest VifIndex: %d%s",
 2146: 	  MAXVIFS - 1,
 2147: 	  VTY_NEWLINE);
 2148: 
 2149:   vty_out(vty, "%s", VTY_NEWLINE);
 2150:   vty_out(vty, "Upstream Join Timer: %d secs%s",
 2151: 	  qpim_t_periodic,
 2152: 	  VTY_NEWLINE);
 2153:   vty_out(vty, "Join/Prune Holdtime: %d secs%s",
 2154: 	  PIM_JP_HOLDTIME,
 2155: 	  VTY_NEWLINE);
 2156: 
 2157:   vty_out(vty, "%s", VTY_NEWLINE);
 2158: 
 2159:   show_rpf_refresh_stats(vty, now);
 2160: 
 2161:   vty_out(vty, "%s", VTY_NEWLINE);
 2162: 
 2163:   show_scan_oil_stats(vty, now);
 2164: 
 2165:   show_multicast_interfaces(vty);
 2166:   
 2167:   return CMD_SUCCESS;
 2168: }
 2169: 
 2170: static void show_mroute(struct vty *vty)
 2171: {
 2172:   struct listnode    *node;
 2173:   struct channel_oil *c_oil;
 2174:   struct static_route *s_route;
 2175:   time_t              now;
 2176: 
 2177:   vty_out(vty, "Proto: I=IGMP P=PIM S=STATIC%s%s", VTY_NEWLINE, VTY_NEWLINE);
 2178:   
 2179:   vty_out(vty, "Source          Group           Proto Input iVifI Output oVifI TTL Uptime  %s",
 2180: 	  VTY_NEWLINE);
 2181: 
 2182:   now = pim_time_monotonic_sec();
 2183: 
 2184:   /* print list of PIM and IGMP routes */
 2185:   for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
 2186:     char group_str[100]; 
 2187:     char source_str[100];
 2188:     int oif_vif_index;
 2189: 
 2190:     pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
 2191:     pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
 2192:     
 2193:     for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
 2194:       struct interface *ifp_in;
 2195:       struct interface *ifp_out;
 2196:       char oif_uptime[10];
 2197:       int ttl;
 2198:       char proto[5];
 2199: 
 2200:       ttl = c_oil->oil.mfcc_ttls[oif_vif_index];
 2201:       if (ttl < 1)
 2202: 	continue;
 2203: 
 2204:       ifp_in  = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
 2205:       ifp_out = pim_if_find_by_vif_index(oif_vif_index);
 2206: 
 2207:       pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - c_oil->oif_creation[oif_vif_index]);
 2208: 
 2209:       proto[0] = '\0';
 2210:       if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
 2211: 	strcat(proto, "P");
 2212:       }
 2213:       if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) {
 2214: 	strcat(proto, "I");
 2215:       }
 2216: 
 2217:       vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
 2218: 	      source_str,
 2219: 	      group_str,
 2220: 	      proto,
 2221: 	      ifp_in ? ifp_in->name : "<iif?>",
 2222: 	      c_oil->oil.mfcc_parent,
 2223: 	      ifp_out ? ifp_out->name : "<oif?>",
 2224: 	      oif_vif_index,
 2225: 	      ttl,
 2226: 	      oif_uptime,
 2227: 	      VTY_NEWLINE);
 2228:     }
 2229:   }
 2230: 
 2231:   /* Print list of static routes */
 2232:   for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
 2233:     char group_str[100];
 2234:     char source_str[100];
 2235:     int oif_vif_index;
 2236: 
 2237:     pim_inet4_dump("<group?>", s_route->group, group_str, sizeof(group_str));
 2238:     pim_inet4_dump("<source?>", s_route->source, source_str, sizeof(source_str));
 2239: 
 2240:     for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
 2241:       struct interface *ifp_in;
 2242:       struct interface *ifp_out;
 2243:       char oif_uptime[10];
 2244:       int ttl;
 2245:       char proto[5];
 2246: 
 2247:       ttl = s_route->oif_ttls[oif_vif_index];
 2248:       if (ttl < 1)
 2249:          continue;
 2250: 
 2251:       ifp_in  = pim_if_find_by_vif_index(s_route->iif);
 2252:       ifp_out = pim_if_find_by_vif_index(oif_vif_index);
 2253: 
 2254:       pim_time_uptime(oif_uptime, sizeof(oif_uptime), now - s_route->creation[oif_vif_index]);
 2255: 
 2256:       proto[0] = '\0';
 2257:       strcat(proto, "S");
 2258: 
 2259:       vty_out(vty, "%-15s %-15s %-5s %-5s %5d %-6s %5d %3d %8s %s",
 2260:          source_str,
 2261:          group_str,
 2262:          proto,
 2263:          ifp_in ? ifp_in->name : "<iif?>",
 2264:          s_route->iif,
 2265:          ifp_out ? ifp_out->name : "<oif?>",
 2266:          oif_vif_index,
 2267:          ttl,
 2268:          oif_uptime,
 2269:          VTY_NEWLINE);
 2270:     }
 2271:   }
 2272: }
 2273: 
 2274: DEFUN (show_ip_mroute,
 2275:        show_ip_mroute_cmd,
 2276:        "show ip mroute",
 2277:        SHOW_STR
 2278:        IP_STR
 2279:        MROUTE_STR)
 2280: {
 2281:   show_mroute(vty);
 2282:   return CMD_SUCCESS;
 2283: }
 2284: 
 2285: static void show_mroute_count(struct vty *vty)
 2286: {
 2287:   struct listnode    *node;
 2288:   struct channel_oil *c_oil;
 2289:   struct static_route *s_route;
 2290: 
 2291:   vty_out(vty, "%s", VTY_NEWLINE);
 2292:   
 2293:   vty_out(vty, "Source          Group           Packets      Bytes WrongIf  %s",
 2294: 	  VTY_NEWLINE);
 2295: 
 2296:   /* Print PIM and IGMP route counts */
 2297:   for (ALL_LIST_ELEMENTS_RO(qpim_channel_oil_list, node, c_oil)) {
 2298:     char group_str[100]; 
 2299:     char source_str[100];
 2300:     struct sioc_sg_req sgreq;
 2301: 
 2302:     memset(&sgreq, 0, sizeof(sgreq));
 2303:     sgreq.src = c_oil->oil.mfcc_origin;
 2304:     sgreq.grp = c_oil->oil.mfcc_mcastgrp;
 2305: 
 2306:     pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str));
 2307:     pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str));
 2308: 
 2309:     if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
 2310:       int e = errno;
 2311:       vty_out(vty,
 2312: 	      "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s,%s): errno=%d: %s%s",
 2313: 	      (unsigned long)SIOCGETSGCNT,
 2314: 	      source_str,
 2315: 	      group_str,
 2316: 	      e,
 2317: 	      safe_strerror(e),
 2318: 	      VTY_NEWLINE);	      
 2319:       continue;
 2320:     }
 2321:     
 2322:     vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
 2323: 	    source_str,
 2324: 	    group_str,
 2325: 	    sgreq.pktcnt,
 2326: 	    sgreq.bytecnt,
 2327: 	    sgreq.wrong_if,
 2328: 	    VTY_NEWLINE);
 2329:   }
 2330: 
 2331:    /* Print static route counts */
 2332:   for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
 2333:     char group_str[100];
 2334:     char source_str[100];
 2335:     struct sioc_sg_req sgreq;
 2336: 
 2337:     memset(&sgreq, 0, sizeof(sgreq));
 2338:     sgreq.src = s_route->mc.mfcc_origin;
 2339:     sgreq.grp = s_route->mc.mfcc_mcastgrp;
 2340: 
 2341:     pim_inet4_dump("<group?>", s_route->mc.mfcc_mcastgrp, group_str, sizeof(group_str));
 2342:     pim_inet4_dump("<source?>", s_route->mc.mfcc_origin, source_str, sizeof(source_str));
 2343: 
 2344:     if (ioctl(qpim_mroute_socket_fd, SIOCGETSGCNT, &sgreq)) {
 2345:       int e = errno;
 2346:       vty_out(vty,
 2347:          "ioctl(SIOCGETSGCNT=%lu) failure for (S,G)=(%s,%s): errno=%d: %s%s",
 2348:          /* note that typeof ioctl defs can vary across platforms, from
 2349:           * int, to unsigned int, to long unsigned int
 2350:           */
 2351:          (unsigned long)SIOCGETSGCNT,
 2352:          source_str,
 2353:          group_str,
 2354:          e,
 2355:          safe_strerror(e),
 2356:          VTY_NEWLINE);
 2357:       continue;
 2358:     }
 2359: 
 2360:     vty_out(vty, "%-15s %-15s %7ld %10ld %7ld %s",
 2361:        source_str,
 2362:        group_str,
 2363:        sgreq.pktcnt,
 2364:        sgreq.bytecnt,
 2365:        sgreq.wrong_if,
 2366:        VTY_NEWLINE);
 2367:   }
 2368: }
 2369: 
 2370: DEFUN (show_ip_mroute_count,
 2371:        show_ip_mroute_count_cmd,
 2372:        "show ip mroute count",
 2373:        SHOW_STR
 2374:        IP_STR
 2375:        MROUTE_STR
 2376:        "Route and packet count data\n")
 2377: {
 2378:   show_mroute_count(vty);
 2379:   return CMD_SUCCESS;
 2380: }
 2381: 
 2382: DEFUN (show_ip_rib,
 2383:        show_ip_rib_cmd,
 2384:        "show ip rib A.B.C.D",
 2385:        SHOW_STR
 2386:        IP_STR
 2387:        RIB_STR
 2388:        "Unicast address\n")
 2389: {
 2390:   struct in_addr addr;
 2391:   const char *addr_str;
 2392:   struct pim_nexthop nexthop;
 2393:   char nexthop_addr_str[100];
 2394:   int result;
 2395: 
 2396:   addr_str = argv[0];
 2397:   result = inet_pton(AF_INET, addr_str, &addr);
 2398:   if (result <= 0) {
 2399:     vty_out(vty, "Bad unicast address %s: errno=%d: %s%s",
 2400: 	    addr_str, errno, safe_strerror(errno), VTY_NEWLINE);
 2401:     return CMD_WARNING;
 2402:   }
 2403: 
 2404:   if (pim_nexthop_lookup(&nexthop, addr)) {
 2405:     vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s",
 2406: 	    addr_str, VTY_NEWLINE);
 2407:     return CMD_WARNING;
 2408:   }
 2409: 
 2410:   vty_out(vty, "Address         NextHop         Interface Metric Preference%s",
 2411: 	  VTY_NEWLINE);
 2412: 
 2413:   pim_inet4_dump("<nexthop?>", nexthop.mrib_nexthop_addr,
 2414: 		 nexthop_addr_str, sizeof(nexthop_addr_str));
 2415: 
 2416:   vty_out(vty, "%-15s %-15s %-9s %6d %10d%s",
 2417: 	  addr_str,
 2418: 	  nexthop_addr_str,
 2419: 	  nexthop.interface ? nexthop.interface->name : "<ifname?>",
 2420: 	  nexthop.mrib_route_metric,
 2421: 	  nexthop.mrib_metric_preference,
 2422: 	  VTY_NEWLINE);
 2423: 
 2424:   return CMD_SUCCESS;
 2425: }
 2426: 
 2427: static void show_ssmpingd(struct vty *vty)
 2428: {
 2429:   struct listnode      *node;
 2430:   struct ssmpingd_sock *ss;
 2431:   time_t                now;
 2432: 
 2433:   vty_out(vty, "Source          Socket Address          Port Uptime   Requests%s",
 2434: 	  VTY_NEWLINE);
 2435: 
 2436:   if (!qpim_ssmpingd_list)
 2437:     return;
 2438: 
 2439:   now = pim_time_monotonic_sec();
 2440: 
 2441:   for (ALL_LIST_ELEMENTS_RO(qpim_ssmpingd_list, node, ss)) {
 2442:     char source_str[100];
 2443:     char ss_uptime[10];
 2444:     struct sockaddr_in bind_addr;
 2445:     socklen_t len = sizeof(bind_addr);
 2446:     char bind_addr_str[100];
 2447: 
 2448:     pim_inet4_dump("<src?>", ss->source_addr, source_str, sizeof(source_str));
 2449: 
 2450:     if (pim_socket_getsockname(ss->sock_fd, (struct sockaddr *) &bind_addr, &len)) {
 2451:       vty_out(vty, "%% Failure reading socket name for ssmpingd source %s on fd=%d%s",
 2452: 	      source_str, ss->sock_fd, VTY_NEWLINE);
 2453:     }
 2454: 
 2455:     pim_inet4_dump("<addr?>", bind_addr.sin_addr, bind_addr_str, sizeof(bind_addr_str));
 2456:     pim_time_uptime(ss_uptime, sizeof(ss_uptime), now - ss->creation);
 2457: 
 2458:     vty_out(vty, "%-15s %6d %-15s %5d %8s %8lld%s",
 2459: 	    source_str,
 2460: 	    ss->sock_fd,
 2461: 	    bind_addr_str,
 2462: 	    ntohs(bind_addr.sin_port),
 2463: 	    ss_uptime,
 2464: 	    (long long)ss->requests,
 2465: 	    VTY_NEWLINE);
 2466:   }
 2467: }
 2468: 
 2469: DEFUN (show_ip_ssmpingd,
 2470:        show_ip_ssmpingd_cmd,
 2471:        "show ip ssmpingd",
 2472:        SHOW_STR
 2473:        IP_STR
 2474:        SHOW_SSMPINGD_STR)
 2475: {
 2476:   show_ssmpingd(vty);
 2477:   return CMD_SUCCESS;
 2478: }
 2479: 
 2480: DEFUN (ip_multicast_routing,
 2481:        ip_multicast_routing_cmd,
 2482:        PIM_CMD_IP_MULTICAST_ROUTING,
 2483:        IP_STR
 2484:        "Enable IP multicast forwarding\n")
 2485: {
 2486:   pim_mroute_socket_enable();
 2487:   pim_if_add_vif_all();
 2488:   mroute_add_all();
 2489:   static_mroute_add_all();
 2490:   return CMD_SUCCESS;
 2491: }
 2492: 
 2493: DEFUN (no_ip_multicast_routing,
 2494:        no_ip_multicast_routing_cmd,
 2495:        PIM_CMD_NO " " PIM_CMD_IP_MULTICAST_ROUTING,
 2496:        NO_STR
 2497:        IP_STR
 2498:        "Global IP configuration subcommands\n"
 2499:        "Enable IP multicast forwarding\n")
 2500: {
 2501:   mroute_del_all();
 2502:   static_mroute_del_all();
 2503:   pim_if_del_vif_all();
 2504:   pim_mroute_socket_disable();
 2505:   return CMD_SUCCESS;
 2506: }
 2507: 
 2508: DEFUN (ip_ssmpingd,
 2509:        ip_ssmpingd_cmd,
 2510:        "ip ssmpingd [A.B.C.D]",
 2511:        IP_STR
 2512:        CONF_SSMPINGD_STR
 2513:        "Source address\n")
 2514: {
 2515:   int result;
 2516:   struct in_addr source_addr;
 2517:   const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
 2518: 
 2519:   result = inet_pton(AF_INET, source_str, &source_addr);
 2520:   if (result <= 0) {
 2521:     vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
 2522: 	    source_str, errno, safe_strerror(errno), VTY_NEWLINE);
 2523:     return CMD_WARNING;
 2524:   }
 2525: 
 2526:   result = pim_ssmpingd_start(source_addr);
 2527:   if (result) {
 2528:     vty_out(vty, "%% Failure starting ssmpingd for source %s: %d%s",
 2529: 	    source_str, result, VTY_NEWLINE);
 2530:     return CMD_WARNING;
 2531:   }
 2532: 
 2533:   return CMD_SUCCESS;
 2534: }
 2535: 
 2536: DEFUN (no_ip_ssmpingd,
 2537:        no_ip_ssmpingd_cmd,
 2538:        "no ip ssmpingd [A.B.C.D]",
 2539:        NO_STR
 2540:        IP_STR
 2541:        CONF_SSMPINGD_STR
 2542:        "Source address\n")
 2543: {
 2544:   int result;
 2545:   struct in_addr source_addr;
 2546:   const char *source_str = (argc > 0) ? argv[0] : "0.0.0.0";
 2547: 
 2548:   result = inet_pton(AF_INET, source_str, &source_addr);
 2549:   if (result <= 0) {
 2550:     vty_out(vty, "%% Bad source address %s: errno=%d: %s%s",
 2551: 	    source_str, errno, safe_strerror(errno), VTY_NEWLINE);
 2552:     return CMD_WARNING;
 2553:   }
 2554: 
 2555:   result = pim_ssmpingd_stop(source_addr);
 2556:   if (result) {
 2557:     vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d%s",
 2558: 	    source_str, result, VTY_NEWLINE);
 2559:     return CMD_WARNING;
 2560:   }
 2561: 
 2562:   return CMD_SUCCESS;
 2563: }
 2564: 
 2565: DEFUN (interface_ip_igmp,
 2566:        interface_ip_igmp_cmd,
 2567:        "ip igmp",
 2568:        IP_STR
 2569:        IFACE_IGMP_STR)
 2570: {
 2571:   struct interface *ifp;
 2572:   struct pim_interface *pim_ifp;
 2573: 
 2574:   ifp = vty->index;
 2575:   pim_ifp = ifp->info;
 2576: 
 2577:   if (!pim_ifp) {
 2578:     pim_ifp = pim_if_new(ifp, 1 /* igmp=true */, 0 /* pim=false */);
 2579:     if (!pim_ifp) {
 2580:       vty_out(vty, "Could not enable IGMP on interface %s%s",
 2581: 	      ifp->name, VTY_NEWLINE);
 2582:       return CMD_WARNING;
 2583:     }
 2584:   }
 2585:   else {
 2586:     PIM_IF_DO_IGMP(pim_ifp->options);
 2587:   }
 2588: 
 2589:   pim_if_addr_add_all(ifp);
 2590:   pim_if_membership_refresh(ifp);
 2591: 
 2592:   return CMD_SUCCESS;
 2593: }
 2594: 
 2595: DEFUN (interface_no_ip_igmp,
 2596:        interface_no_ip_igmp_cmd,
 2597:        "no ip igmp",
 2598:        NO_STR
 2599:        IP_STR
 2600:        IFACE_IGMP_STR)
 2601: {
 2602:   struct interface *ifp;
 2603:   struct pim_interface *pim_ifp;
 2604: 
 2605:   ifp = vty->index;
 2606:   pim_ifp = ifp->info;
 2607:   if (!pim_ifp)
 2608:     return CMD_SUCCESS;
 2609: 
 2610:   PIM_IF_DONT_IGMP(pim_ifp->options);
 2611: 
 2612:   pim_if_membership_clear(ifp);
 2613: 
 2614:   pim_if_addr_del_all_igmp(ifp);
 2615: 
 2616:   if (!PIM_IF_TEST_PIM(pim_ifp->options)) {
 2617:     pim_if_delete(ifp);
 2618:   }
 2619: 
 2620:   return CMD_SUCCESS;
 2621: }
 2622: 
 2623: DEFUN (interface_ip_igmp_join,
 2624:        interface_ip_igmp_join_cmd,
 2625:        "ip igmp join A.B.C.D A.B.C.D",
 2626:        IP_STR
 2627:        IFACE_IGMP_STR
 2628:        "IGMP join multicast group\n"
 2629:        "Multicast group address\n"
 2630:        "Source address\n")
 2631: {
 2632:   struct interface *ifp;
 2633:   const char *group_str;
 2634:   const char *source_str;
 2635:   struct in_addr group_addr;
 2636:   struct in_addr source_addr;
 2637:   int result;
 2638: 
 2639:   ifp = vty->index;
 2640: 
 2641:   /* Group address */
 2642:   group_str = argv[0];
 2643:   result = inet_pton(AF_INET, group_str, &group_addr);
 2644:   if (result <= 0) {
 2645:     vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 2646: 	    group_str, errno, safe_strerror(errno), VTY_NEWLINE);
 2647:     return CMD_WARNING;
 2648:   }
 2649: 
 2650:   /* Source address */
 2651:   source_str = argv[1];
 2652:   result = inet_pton(AF_INET, source_str, &source_addr);
 2653:   if (result <= 0) {
 2654:     vty_out(vty, "Bad source address %s: errno=%d: %s%s",
 2655: 	    source_str, errno, safe_strerror(errno), VTY_NEWLINE);
 2656:     return CMD_WARNING;
 2657:   }
 2658: 
 2659:   result = pim_if_igmp_join_add(ifp, group_addr, source_addr);
 2660:   if (result) {
 2661:     vty_out(vty, "%% Failure joining IGMP group %s source %s on interface %s: %d%s",
 2662: 	    group_str, source_str, ifp->name, result, VTY_NEWLINE);
 2663:     return CMD_WARNING;
 2664:   }
 2665: 
 2666:   return CMD_SUCCESS;
 2667: }
 2668: 
 2669: DEFUN (interface_no_ip_igmp_join,
 2670:        interface_no_ip_igmp_join_cmd,
 2671:        "no ip igmp join A.B.C.D A.B.C.D",
 2672:        NO_STR
 2673:        IP_STR
 2674:        IFACE_IGMP_STR
 2675:        "IGMP join multicast group\n"
 2676:        "Multicast group address\n"
 2677:        "Source address\n")
 2678: {
 2679:   struct interface *ifp;
 2680:   const char *group_str;
 2681:   const char *source_str;
 2682:   struct in_addr group_addr;
 2683:   struct in_addr source_addr;
 2684:   int result;
 2685: 
 2686:   ifp = vty->index;
 2687: 
 2688:   /* Group address */
 2689:   group_str = argv[0];
 2690:   result = inet_pton(AF_INET, group_str, &group_addr);
 2691:   if (result <= 0) {
 2692:     vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 2693: 	    group_str, errno, safe_strerror(errno), VTY_NEWLINE);
 2694:     return CMD_WARNING;
 2695:   }
 2696: 
 2697:   /* Source address */
 2698:   source_str = argv[1];
 2699:   result = inet_pton(AF_INET, source_str, &source_addr);
 2700:   if (result <= 0) {
 2701:     vty_out(vty, "Bad source address %s: errno=%d: %s%s",
 2702: 	    source_str, errno, safe_strerror(errno), VTY_NEWLINE);
 2703:     return CMD_WARNING;
 2704:   }
 2705: 
 2706:   result = pim_if_igmp_join_del(ifp, group_addr, source_addr);
 2707:   if (result) {
 2708:     vty_out(vty, "%% Failure leaving IGMP group %s source %s on interface %s: %d%s",
 2709: 	    group_str, source_str, ifp->name, result, VTY_NEWLINE);
 2710:     return CMD_WARNING;
 2711:   }
 2712: 
 2713:   return CMD_SUCCESS;
 2714: }
 2715: 
 2716: /*
 2717:   CLI reconfiguration affects the interface level (struct pim_interface).
 2718:   This function propagates the reconfiguration to every active socket
 2719:   for that interface.
 2720:  */
 2721: static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
 2722: {
 2723:   struct interface *ifp;
 2724:   struct pim_interface *pim_ifp;
 2725: 
 2726:   zassert(igmp);
 2727: 
 2728:   /* other querier present? */
 2729: 
 2730:   if (igmp->t_other_querier_timer)
 2731:     return;
 2732: 
 2733:   /* this is the querier */
 2734: 
 2735:   zassert(igmp->interface);
 2736:   zassert(igmp->interface->info);
 2737: 
 2738:   ifp = igmp->interface;
 2739:   pim_ifp = ifp->info;
 2740: 
 2741:   if (PIM_DEBUG_IGMP_TRACE) {
 2742:     char ifaddr_str[100];
 2743:     pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str, sizeof(ifaddr_str));
 2744:     zlog_debug("%s: Querier %s on %s reconfig query_interval=%d",
 2745: 	       __PRETTY_FUNCTION__,
 2746: 	       ifaddr_str,
 2747: 	       ifp->name,
 2748: 	       pim_ifp->igmp_default_query_interval);
 2749:   }
 2750: 
 2751:   /*
 2752:     igmp_startup_mode_on() will reset QQI:
 2753: 
 2754:     igmp->querier_query_interval = pim_ifp->igmp_default_query_interval;
 2755:   */
 2756:   igmp_startup_mode_on(igmp);
 2757: }
 2758: 
 2759: static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
 2760: {
 2761:   if (igmp->t_igmp_query_timer) {
 2762:     /* other querier present */
 2763:     zassert(igmp->t_igmp_query_timer);
 2764:     zassert(!igmp->t_other_querier_timer);
 2765: 
 2766:     pim_igmp_general_query_off(igmp);
 2767:     pim_igmp_general_query_on(igmp);
 2768: 
 2769:     zassert(igmp->t_igmp_query_timer);
 2770:     zassert(!igmp->t_other_querier_timer);
 2771:   }
 2772:   else {
 2773:     /* this is the querier */
 2774: 
 2775:     zassert(!igmp->t_igmp_query_timer);
 2776:     zassert(igmp->t_other_querier_timer);
 2777: 
 2778:     pim_igmp_other_querier_timer_off(igmp);
 2779:     pim_igmp_other_querier_timer_on(igmp);
 2780: 
 2781:     zassert(!igmp->t_igmp_query_timer);
 2782:     zassert(igmp->t_other_querier_timer);
 2783:   }
 2784: }
 2785: 
 2786: static void change_query_interval(struct pim_interface *pim_ifp,
 2787: 				  int query_interval)
 2788: {
 2789:   struct listnode  *sock_node;
 2790:   struct igmp_sock *igmp;
 2791: 
 2792:   pim_ifp->igmp_default_query_interval = query_interval;
 2793: 
 2794:   for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
 2795:     igmp_sock_query_interval_reconfig(igmp);
 2796:     igmp_sock_query_reschedule(igmp);
 2797:   }
 2798: }
 2799: 
 2800: static void change_query_max_response_time(struct pim_interface *pim_ifp,
 2801: 					   int query_max_response_time_dsec)
 2802: {
 2803:   struct listnode  *sock_node;
 2804:   struct igmp_sock *igmp;
 2805: 
 2806:   pim_ifp->igmp_query_max_response_time_dsec = query_max_response_time_dsec;
 2807: 
 2808:   /*
 2809:     Below we modify socket/group/source timers in order to quickly
 2810:     reflect the change. Otherwise, those timers would eventually catch
 2811:     up.
 2812:    */
 2813: 
 2814:   /* scan all sockets */
 2815:   for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
 2816:     struct listnode   *grp_node;
 2817:     struct igmp_group *grp;
 2818: 
 2819:     /* reschedule socket general query */
 2820:     igmp_sock_query_reschedule(igmp);
 2821: 
 2822:     /* scan socket groups */
 2823:     for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node, grp)) {
 2824:       struct listnode    *src_node;
 2825:       struct igmp_source *src;
 2826: 
 2827:       /* reset group timers for groups in EXCLUDE mode */
 2828:       if (grp->group_filtermode_isexcl) {
 2829: 	igmp_group_reset_gmi(grp);
 2830:       }
 2831: 
 2832:       /* scan group sources */
 2833:       for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node, src)) {
 2834: 
 2835: 	/* reset source timers for sources with running timers */
 2836: 	if (src->t_source_timer) {
 2837: 	  igmp_source_reset_gmi(igmp, grp, src);
 2838: 	}
 2839:       }
 2840:     }
 2841:   }
 2842: }
 2843: 
 2844: #define IGMP_QUERY_INTERVAL_MIN (1)
 2845: #define IGMP_QUERY_INTERVAL_MAX (1800)
 2846: 
 2847: DEFUN (interface_ip_igmp_query_interval,
 2848:        interface_ip_igmp_query_interval_cmd,
 2849:        PIM_CMD_IP_IGMP_QUERY_INTERVAL " <1-1800>",
 2850:        IP_STR
 2851:        IFACE_IGMP_STR
 2852:        IFACE_IGMP_QUERY_INTERVAL_STR
 2853:        "Query interval in seconds\n")
 2854: {
 2855:   struct interface *ifp;
 2856:   struct pim_interface *pim_ifp;
 2857:   int query_interval;
 2858:   int query_interval_dsec;
 2859: 
 2860:   ifp = vty->index;
 2861:   pim_ifp = ifp->info;
 2862: 
 2863:   if (!pim_ifp) {
 2864:     vty_out(vty,
 2865: 	    "IGMP not enabled on interface %s. Please enable IGMP first.%s",
 2866: 	    ifp->name,
 2867: 	    VTY_NEWLINE);
 2868:     return CMD_WARNING;
 2869:   }
 2870: 
 2871:   query_interval = atoi(argv[0]);
 2872:   query_interval_dsec = 10 * query_interval;
 2873: 
 2874:   /*
 2875:     It seems we don't need to check bounds since command.c does it
 2876:     already, but we verify them anyway for extra safety.
 2877:   */
 2878:   if (query_interval < IGMP_QUERY_INTERVAL_MIN) {
 2879:     vty_out(vty, "General query interval %d lower than minimum %d%s",
 2880: 	    query_interval,
 2881: 	    IGMP_QUERY_INTERVAL_MIN,
 2882: 	    VTY_NEWLINE);
 2883:     return CMD_WARNING;
 2884:   }
 2885:   if (query_interval > IGMP_QUERY_INTERVAL_MAX) {
 2886:     vty_out(vty, "General query interval %d higher than maximum %d%s",
 2887: 	    query_interval,
 2888: 	    IGMP_QUERY_INTERVAL_MAX,
 2889: 	    VTY_NEWLINE);
 2890:     return CMD_WARNING;
 2891:   }
 2892: 
 2893:   if (query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
 2894:     vty_out(vty,
 2895: 	    "Can't set general query interval %d dsec <= query max response time %d dsec.%s",
 2896: 	    query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
 2897: 	    VTY_NEWLINE);
 2898:     return CMD_WARNING;
 2899:   }
 2900: 
 2901:   change_query_interval(pim_ifp, query_interval);
 2902: 
 2903:   return CMD_SUCCESS;
 2904: }
 2905: 
 2906: DEFUN (interface_no_ip_igmp_query_interval,
 2907:        interface_no_ip_igmp_query_interval_cmd,
 2908:        PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_INTERVAL,
 2909:        NO_STR
 2910:        IP_STR
 2911:        IFACE_IGMP_STR
 2912:        IFACE_IGMP_QUERY_INTERVAL_STR)
 2913: {
 2914:   struct interface *ifp;
 2915:   struct pim_interface *pim_ifp;
 2916:   int default_query_interval_dsec;
 2917: 
 2918:   ifp = vty->index;
 2919:   pim_ifp = ifp->info;
 2920: 
 2921:   if (!pim_ifp)
 2922:     return CMD_SUCCESS;
 2923: 
 2924:   default_query_interval_dsec = IGMP_GENERAL_QUERY_INTERVAL * 10;
 2925: 
 2926:   if (default_query_interval_dsec <= pim_ifp->igmp_query_max_response_time_dsec) {
 2927:     vty_out(vty,
 2928: 	    "Can't set default general query interval %d dsec <= query max response time %d dsec.%s",
 2929: 	    default_query_interval_dsec, pim_ifp->igmp_query_max_response_time_dsec,
 2930: 	    VTY_NEWLINE);
 2931:     return CMD_WARNING;
 2932:   }
 2933: 
 2934:   change_query_interval(pim_ifp, IGMP_GENERAL_QUERY_INTERVAL);
 2935: 
 2936:   return CMD_SUCCESS;
 2937: }
 2938: 
 2939: #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN (1)
 2940: #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX (25)
 2941: 
 2942: DEFUN (interface_ip_igmp_query_max_response_time,
 2943:        interface_ip_igmp_query_max_response_time_cmd,
 2944:        PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME " <1-25>",
 2945:        IP_STR
 2946:        IFACE_IGMP_STR
 2947:        IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
 2948:        "Query response value in seconds\n")
 2949: {
 2950:   struct interface *ifp;
 2951:   struct pim_interface *pim_ifp;
 2952:   int query_max_response_time;
 2953: 
 2954:   ifp = vty->index;
 2955:   pim_ifp = ifp->info;
 2956: 
 2957:   if (!pim_ifp) {
 2958:     vty_out(vty,
 2959: 	    "IGMP not enabled on interface %s. Please enable IGMP first.%s",
 2960: 	    ifp->name,
 2961: 	    VTY_NEWLINE);
 2962:     return CMD_WARNING;
 2963:   }
 2964: 
 2965:   query_max_response_time = atoi(argv[0]);
 2966: 
 2967:   /*
 2968:     It seems we don't need to check bounds since command.c does it
 2969:     already, but we verify them anyway for extra safety.
 2970:   */
 2971:   if (query_max_response_time < IGMP_QUERY_MAX_RESPONSE_TIME_MIN) {
 2972:     vty_out(vty, "Query max response time %d sec lower than minimum %d sec%s",
 2973: 	    query_max_response_time,
 2974: 	    IGMP_QUERY_MAX_RESPONSE_TIME_MIN,
 2975: 	    VTY_NEWLINE);
 2976:     return CMD_WARNING;
 2977:   }
 2978:   if (query_max_response_time > IGMP_QUERY_MAX_RESPONSE_TIME_MAX) {
 2979:     vty_out(vty, "Query max response time %d sec higher than maximum %d sec%s",
 2980: 	    query_max_response_time,
 2981: 	    IGMP_QUERY_MAX_RESPONSE_TIME_MAX,
 2982: 	    VTY_NEWLINE);
 2983:     return CMD_WARNING;
 2984:   }
 2985: 
 2986:   if (query_max_response_time >= pim_ifp->igmp_default_query_interval) {
 2987:     vty_out(vty,
 2988: 	    "Can't set query max response time %d sec >= general query interval %d sec%s",
 2989: 	    query_max_response_time, pim_ifp->igmp_default_query_interval,
 2990: 	    VTY_NEWLINE);
 2991:     return CMD_WARNING;
 2992:   }
 2993: 
 2994:   change_query_max_response_time(pim_ifp, 10 * query_max_response_time);
 2995: 
 2996:   return CMD_SUCCESS;
 2997: }
 2998: 
 2999: DEFUN (interface_no_ip_igmp_query_max_response_time,
 3000:        interface_no_ip_igmp_query_max_response_time_cmd,
 3001:        PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME,
 3002:        NO_STR
 3003:        IP_STR
 3004:        IFACE_IGMP_STR
 3005:        IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
 3006: {
 3007:   struct interface *ifp;
 3008:   struct pim_interface *pim_ifp;
 3009:   int default_query_interval_dsec;
 3010: 
 3011:   ifp = vty->index;
 3012:   pim_ifp = ifp->info;
 3013: 
 3014:   if (!pim_ifp)
 3015:     return CMD_SUCCESS;
 3016: 
 3017:   default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
 3018: 
 3019:   if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
 3020:     vty_out(vty,
 3021: 	    "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
 3022: 	    IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
 3023: 	    VTY_NEWLINE);
 3024:     return CMD_WARNING;
 3025:   }
 3026: 
 3027:   change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
 3028: 
 3029:   return CMD_SUCCESS;
 3030: }
 3031: 
 3032: #define IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC (10)
 3033: #define IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC (250)
 3034: 
 3035: DEFUN (interface_ip_igmp_query_max_response_time_dsec,
 3036:        interface_ip_igmp_query_max_response_time_dsec_cmd,
 3037:        PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC " <10-250>",
 3038:        IP_STR
 3039:        IFACE_IGMP_STR
 3040:        IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR
 3041:        "Query response value in deciseconds\n")
 3042: {
 3043:   struct interface *ifp;
 3044:   struct pim_interface *pim_ifp;
 3045:   int query_max_response_time_dsec;
 3046:   int default_query_interval_dsec;
 3047: 
 3048:   ifp = vty->index;
 3049:   pim_ifp = ifp->info;
 3050: 
 3051:   if (!pim_ifp) {
 3052:     vty_out(vty,
 3053: 	    "IGMP not enabled on interface %s. Please enable IGMP first.%s",
 3054: 	    ifp->name,
 3055: 	    VTY_NEWLINE);
 3056:     return CMD_WARNING;
 3057:   }
 3058: 
 3059:   query_max_response_time_dsec = atoi(argv[0]);
 3060: 
 3061:   /*
 3062:     It seems we don't need to check bounds since command.c does it
 3063:     already, but we verify them anyway for extra safety.
 3064:   */
 3065:   if (query_max_response_time_dsec < IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC) {
 3066:     vty_out(vty, "Query max response time %d dsec lower than minimum %d dsec%s",
 3067: 	    query_max_response_time_dsec,
 3068: 	    IGMP_QUERY_MAX_RESPONSE_TIME_MIN_DSEC,
 3069: 	    VTY_NEWLINE);
 3070:     return CMD_WARNING;
 3071:   }
 3072:   if (query_max_response_time_dsec > IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC) {
 3073:     vty_out(vty, "Query max response time %d dsec higher than maximum %d dsec%s",
 3074: 	    query_max_response_time_dsec,
 3075: 	    IGMP_QUERY_MAX_RESPONSE_TIME_MAX_DSEC,
 3076: 	    VTY_NEWLINE);
 3077:     return CMD_WARNING;
 3078:   }
 3079: 
 3080:   default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
 3081: 
 3082:   if (query_max_response_time_dsec >= default_query_interval_dsec) {
 3083:     vty_out(vty,
 3084: 	    "Can't set query max response time %d dsec >= general query interval %d dsec%s",
 3085: 	    query_max_response_time_dsec, default_query_interval_dsec,
 3086: 	    VTY_NEWLINE);
 3087:     return CMD_WARNING;
 3088:   }
 3089: 
 3090:   change_query_max_response_time(pim_ifp, query_max_response_time_dsec);
 3091: 
 3092:   return CMD_SUCCESS;
 3093: }
 3094: 
 3095: DEFUN (interface_no_ip_igmp_query_max_response_time_dsec,
 3096:        interface_no_ip_igmp_query_max_response_time_dsec_cmd,
 3097:        PIM_CMD_NO " " PIM_CMD_IP_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC,
 3098:        NO_STR
 3099:        IP_STR
 3100:        IFACE_IGMP_STR
 3101:        IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR)
 3102: {
 3103:   struct interface *ifp;
 3104:   struct pim_interface *pim_ifp;
 3105:   int default_query_interval_dsec;
 3106: 
 3107:   ifp = vty->index;
 3108:   pim_ifp = ifp->info;
 3109: 
 3110:   if (!pim_ifp)
 3111:     return CMD_SUCCESS;
 3112: 
 3113:   default_query_interval_dsec = 10 * pim_ifp->igmp_default_query_interval;
 3114: 
 3115:   if (IGMP_QUERY_MAX_RESPONSE_TIME_DSEC >= default_query_interval_dsec) {
 3116:     vty_out(vty,
 3117: 	    "Can't set default query max response time %d dsec >= general query interval %d dsec.%s",
 3118: 	    IGMP_QUERY_MAX_RESPONSE_TIME_DSEC, default_query_interval_dsec,
 3119: 	    VTY_NEWLINE);
 3120:     return CMD_WARNING;
 3121:   }
 3122: 
 3123:   change_query_max_response_time(pim_ifp, IGMP_QUERY_MAX_RESPONSE_TIME_DSEC);
 3124: 
 3125:   return CMD_SUCCESS;
 3126: }
 3127: 
 3128: DEFUN (interface_ip_pim_drprio,
 3129:        interface_ip_pim_drprio_cmd,
 3130:        "ip pim drpriority <1-4294967295>",
 3131:        IP_STR
 3132:        PIM_STR
 3133:        "Set the Designated Router Election Priority\n"
 3134:        "Value of the new DR Priority\n")
 3135: {
 3136:   struct interface *ifp;
 3137:   struct pim_interface *pim_ifp;
 3138:   uint32_t old_dr_prio;
 3139: 
 3140:   ifp = vty->index;
 3141:   pim_ifp = ifp->info;
 3142: 
 3143:   if (!pim_ifp) {
 3144:     vty_out(vty, "Please enable PIM on interface, first%s", VTY_NEWLINE);
 3145:     return CMD_WARNING;
 3146:   }
 3147: 
 3148:   old_dr_prio = pim_ifp->pim_dr_priority;
 3149: 
 3150:   pim_ifp->pim_dr_priority = strtol(argv[0], NULL, 10);
 3151: 
 3152:   if (old_dr_prio != pim_ifp->pim_dr_priority) {
 3153:     if (pim_if_dr_election(ifp))
 3154:       pim_hello_restart_now(ifp);
 3155:   }
 3156: 
 3157:   return CMD_SUCCESS;
 3158: }
 3159: 
 3160: DEFUN (interface_no_ip_pim_drprio,
 3161:        interface_no_ip_pim_drprio_cmd,
 3162:        "no ip pim drpriority {<1-4294967295>}",
 3163:        IP_STR
 3164:        PIM_STR
 3165:        "Revert the Designated Router Priority to default\n"
 3166:        "Old Value of the Priority\n")
 3167: {
 3168:   struct interface *ifp;
 3169:   struct pim_interface *pim_ifp;
 3170: 
 3171:   ifp = vty->index;
 3172:   pim_ifp = ifp->info;
 3173: 
 3174:   if (!pim_ifp) {
 3175:     vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
 3176:     return CMD_WARNING;
 3177:   }
 3178: 
 3179:   if (pim_ifp->pim_dr_priority != PIM_DEFAULT_DR_PRIORITY) {
 3180:     pim_ifp->pim_dr_priority = PIM_DEFAULT_DR_PRIORITY;
 3181:     if (pim_if_dr_election(ifp))
 3182:       pim_hello_restart_now(ifp);
 3183:   }
 3184: 
 3185:   return CMD_SUCCESS;
 3186: }
 3187: 
 3188: DEFUN (interface_ip_pim_ssm,
 3189:        interface_ip_pim_ssm_cmd,
 3190:        "ip pim ssm",
 3191:        IP_STR
 3192:        PIM_STR
 3193:        IFACE_PIM_STR)
 3194: {
 3195:   struct interface *ifp;
 3196:   struct pim_interface *pim_ifp;
 3197: 
 3198:   ifp = vty->index;
 3199:   pim_ifp = ifp->info;
 3200: 
 3201:   if (!pim_ifp) {
 3202:     pim_ifp = pim_if_new(ifp, 0 /* igmp=false */, 1 /* pim=true */);
 3203:     if (!pim_ifp) {
 3204:       vty_out(vty, "Could not enable PIM on interface%s", VTY_NEWLINE);
 3205:       return CMD_WARNING;
 3206:     }
 3207:   }
 3208:   else {
 3209:     PIM_IF_DO_PIM(pim_ifp->options);
 3210:   }
 3211: 
 3212:   pim_if_addr_add_all(ifp);
 3213:   pim_if_membership_refresh(ifp);
 3214: 
 3215:   return CMD_SUCCESS;
 3216: }
 3217: 
 3218: DEFUN (interface_no_ip_pim_ssm,
 3219:        interface_no_ip_pim_ssm_cmd,
 3220:        "no ip pim ssm",
 3221:        NO_STR
 3222:        IP_STR
 3223:        PIM_STR
 3224:        IFACE_PIM_STR)
 3225: {
 3226:   struct interface *ifp;
 3227:   struct pim_interface *pim_ifp;
 3228: 
 3229:   ifp = vty->index;
 3230:   pim_ifp = ifp->info;
 3231:   if (!pim_ifp)
 3232:     return CMD_SUCCESS;
 3233: 
 3234:   PIM_IF_DONT_PIM(pim_ifp->options);
 3235: 
 3236:   pim_if_membership_clear(ifp);
 3237: 
 3238:   /*
 3239:     pim_if_addr_del_all() removes all sockets from
 3240:     pim_ifp->igmp_socket_list.
 3241:    */
 3242:   pim_if_addr_del_all(ifp);
 3243: 
 3244:   /*
 3245:     pim_sock_delete() removes all neighbors from
 3246:     pim_ifp->pim_neighbor_list.
 3247:    */
 3248:   pim_sock_delete(ifp, "pim unconfigured on interface");
 3249: 
 3250:   if (!PIM_IF_TEST_IGMP(pim_ifp->options)) {
 3251:     pim_if_delete(ifp);
 3252:   }
 3253: 
 3254:   return CMD_SUCCESS;
 3255: }
 3256: 
 3257: DEFUN (interface_ip_mroute,
 3258:        interface_ip_mroute_cmd,
 3259:        "ip mroute INTERFACE A.B.C.D",
 3260:        IP_STR
 3261:        "Add multicast route\n"
 3262:        "Outgoing interface name\n"
 3263:        "Group address\n")
 3264: {
 3265:    struct interface *iif;
 3266:    struct interface *oif;
 3267:    const char       *oifname;
 3268:    const char       *grp_str;
 3269:    struct in_addr    grp_addr;
 3270:    struct in_addr    src_addr;
 3271:    int               result;
 3272: 
 3273:    iif = vty->index;
 3274: 
 3275:    oifname = argv[0];
 3276:    oif = if_lookup_by_name(oifname);
 3277:    if (!oif) {
 3278:      vty_out(vty, "No such interface name %s%s",
 3279:         oifname, VTY_NEWLINE);
 3280:      return CMD_WARNING;
 3281:    }
 3282: 
 3283:    grp_str = argv[1];
 3284:    result = inet_pton(AF_INET, grp_str, &grp_addr);
 3285:    if (result <= 0) {
 3286:      vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 3287:         grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
 3288:      return CMD_WARNING;
 3289:    }
 3290: 
 3291:    src_addr.s_addr = INADDR_ANY;
 3292: 
 3293:    if (pim_static_add(iif, oif, grp_addr, src_addr)) {
 3294:       vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
 3295:       return CMD_WARNING;
 3296:    }
 3297: 
 3298:    return CMD_SUCCESS;
 3299: }
 3300: 
 3301: DEFUN (interface_ip_mroute_source,
 3302:        interface_ip_mroute_source_cmd,
 3303:        "ip mroute INTERFACE A.B.C.D A.B.C.D",
 3304:        IP_STR
 3305:        "Add multicast route\n"
 3306:        "Outgoing interface name\n"
 3307:        "Group address\n"
 3308:        "Source address\n")
 3309: {
 3310:    struct interface *iif;
 3311:    struct interface *oif;
 3312:    const char       *oifname;
 3313:    const char       *grp_str;
 3314:    struct in_addr    grp_addr;
 3315:    const char       *src_str;
 3316:    struct in_addr    src_addr;
 3317:    int               result;
 3318: 
 3319:    iif = vty->index;
 3320: 
 3321:    oifname = argv[0];
 3322:    oif = if_lookup_by_name(oifname);
 3323:    if (!oif) {
 3324:      vty_out(vty, "No such interface name %s%s",
 3325:         oifname, VTY_NEWLINE);
 3326:      return CMD_WARNING;
 3327:    }
 3328: 
 3329:    grp_str = argv[1];
 3330:    result = inet_pton(AF_INET, grp_str, &grp_addr);
 3331:    if (result <= 0) {
 3332:      vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 3333:         grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
 3334:      return CMD_WARNING;
 3335:    }
 3336: 
 3337:    src_str = argv[2];
 3338:    result = inet_pton(AF_INET, src_str, &src_addr);
 3339:    if (result <= 0) {
 3340:      vty_out(vty, "Bad source address %s: errno=%d: %s%s",
 3341:         src_str, errno, safe_strerror(errno), VTY_NEWLINE);
 3342:      return CMD_WARNING;
 3343:    }
 3344: 
 3345:    if (pim_static_add(iif, oif, grp_addr, src_addr)) {
 3346:       vty_out(vty, "Failed to add route%s", VTY_NEWLINE);
 3347:       return CMD_WARNING;
 3348:    }
 3349: 
 3350:    return CMD_SUCCESS;
 3351: }
 3352: 
 3353: DEFUN (interface_no_ip_mroute,
 3354:        interface_no_ip_mroute_cmd,
 3355:        "no ip mroute INTERFACE A.B.C.D",
 3356:        NO_STR
 3357:        IP_STR
 3358:        "Add multicast route\n"
 3359:        "Outgoing interface name\n"
 3360:        "Group Address\n")
 3361: {
 3362:    struct interface *iif;
 3363:    struct interface *oif;
 3364:    const char       *oifname;
 3365:    const char       *grp_str;
 3366:    struct in_addr    grp_addr;
 3367:    struct in_addr    src_addr;
 3368:    int               result;
 3369: 
 3370:    iif = vty->index;
 3371: 
 3372:    oifname = argv[0];
 3373:    oif = if_lookup_by_name(oifname);
 3374:    if (!oif) {
 3375:      vty_out(vty, "No such interface name %s%s",
 3376:         oifname, VTY_NEWLINE);
 3377:      return CMD_WARNING;
 3378:    }
 3379: 
 3380:    grp_str = argv[1];
 3381:    result = inet_pton(AF_INET, grp_str, &grp_addr);
 3382:    if (result <= 0) {
 3383:      vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 3384:         grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
 3385:      return CMD_WARNING;
 3386:    }
 3387: 
 3388:    src_addr.s_addr = INADDR_ANY;
 3389: 
 3390:    if (pim_static_del(iif, oif, grp_addr, src_addr)) {
 3391:       vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
 3392:       return CMD_WARNING;
 3393:    }
 3394: 
 3395:    return CMD_SUCCESS;
 3396: }
 3397: 
 3398: DEFUN (interface_no_ip_mroute_source,
 3399:        interface_no_ip_mroute_source_cmd,
 3400:        "no ip mroute INTERFACE A.B.C.D A.B.C.D",
 3401:        NO_STR
 3402:        IP_STR
 3403:        "Add multicast route\n"
 3404:        "Outgoing interface name\n"
 3405:        "Group Address\n"
 3406:        "Source Address\n")
 3407: {
 3408:    struct interface *iif;
 3409:    struct interface *oif;
 3410:    const char       *oifname;
 3411:    const char       *grp_str;
 3412:    struct in_addr    grp_addr;
 3413:    const char       *src_str;
 3414:    struct in_addr    src_addr;
 3415:    int               result;
 3416: 
 3417:    iif = vty->index;
 3418: 
 3419:    oifname = argv[0];
 3420:    oif = if_lookup_by_name(oifname);
 3421:    if (!oif) {
 3422:      vty_out(vty, "No such interface name %s%s",
 3423:         oifname, VTY_NEWLINE);
 3424:      return CMD_WARNING;
 3425:    }
 3426: 
 3427:    grp_str = argv[1];
 3428:    result = inet_pton(AF_INET, grp_str, &grp_addr);
 3429:    if (result <= 0) {
 3430:      vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 3431:         grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
 3432:      return CMD_WARNING;
 3433:    }
 3434: 
 3435:    src_str = argv[2];
 3436:    result = inet_pton(AF_INET, src_str, &src_addr);
 3437:    if (result <= 0) {
 3438:      vty_out(vty, "Bad source address %s: errno=%d: %s%s",
 3439:         src_str, errno, safe_strerror(errno), VTY_NEWLINE);
 3440:      return CMD_WARNING;
 3441:    }
 3442: 
 3443:    if (pim_static_del(iif, oif, grp_addr, src_addr)) {
 3444:       vty_out(vty, "Failed to remove route%s", VTY_NEWLINE);
 3445:       return CMD_WARNING;
 3446:    }
 3447: 
 3448:    return CMD_SUCCESS;
 3449: }
 3450: 
 3451: DEFUN (interface_ip_pim_hello,
 3452:        interface_ip_pim_hello_cmd,
 3453:        "ip pim hello <1-180>",
 3454:        IP_STR
 3455:        PIM_STR
 3456:        IFACE_PIM_HELLO_STR
 3457:        IFACE_PIM_HELLO_TIME_STR)
 3458: {
 3459:   struct interface *ifp;
 3460:   struct pim_interface *pim_ifp;
 3461: 
 3462:   ifp = vty->index;
 3463:   pim_ifp = ifp->info;
 3464: 
 3465:   if (!pim_ifp) {
 3466:     vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
 3467:     return CMD_WARNING;
 3468:   }
 3469: 
 3470:   pim_ifp->pim_hello_period = strtol(argv[0], NULL, 10);
 3471: 
 3472:   if (argc == 2)
 3473:     pim_ifp->pim_default_holdtime = strtol(argv[1], NULL, 10);
 3474: 
 3475:   return CMD_SUCCESS;
 3476: }
 3477: 
 3478: ALIAS (interface_ip_pim_hello,
 3479:        interface_ip_pim_hello_hold_cmd,
 3480:        "ip pim hello <1-180> <1-180>",
 3481:        IP_STR
 3482:        PIM_STR
 3483:        IFACE_PIM_HELLO_STR
 3484:        IFACE_PIM_HELLO_TIME_STR
 3485:        IFACE_PIM_HELLO_HOLD_STR)
 3486: 
 3487: 
 3488: DEFUN (interface_no_ip_pim_hello,
 3489:        interface_no_ip_pim_hello_cmd,
 3490:        "no ip pim hello {<1-180> <1-180>}",
 3491:        NO_STR
 3492:        IP_STR
 3493:        PIM_STR
 3494:        IFACE_PIM_HELLO_STR
 3495:        IFACE_PIM_HELLO_TIME_STR
 3496:        IFACE_PIM_HELLO_HOLD_STR)
 3497: {
 3498:   struct interface *ifp;
 3499:   struct pim_interface *pim_ifp;
 3500: 
 3501:   ifp = vty->index;
 3502:   pim_ifp = ifp->info;
 3503: 
 3504:   if (!pim_ifp) {
 3505:     vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE);
 3506:     return CMD_WARNING;
 3507:   }
 3508: 
 3509:   pim_ifp->pim_hello_period     = PIM_DEFAULT_HELLO_PERIOD;
 3510:   pim_ifp->pim_default_holdtime = -1;
 3511: 
 3512:   return CMD_SUCCESS;
 3513: }
 3514: 
 3515: DEFUN (debug_igmp,
 3516:        debug_igmp_cmd,
 3517:        "debug igmp",
 3518:        DEBUG_STR
 3519:        DEBUG_IGMP_STR)
 3520: {
 3521:   PIM_DO_DEBUG_IGMP_EVENTS;
 3522:   PIM_DO_DEBUG_IGMP_PACKETS;
 3523:   PIM_DO_DEBUG_IGMP_TRACE;
 3524:   return CMD_SUCCESS;
 3525: }
 3526: 
 3527: DEFUN (no_debug_igmp,
 3528:        no_debug_igmp_cmd,
 3529:        "no debug igmp",
 3530:        NO_STR
 3531:        DEBUG_STR
 3532:        DEBUG_IGMP_STR)
 3533: {
 3534:   PIM_DONT_DEBUG_IGMP_EVENTS;
 3535:   PIM_DONT_DEBUG_IGMP_PACKETS;
 3536:   PIM_DONT_DEBUG_IGMP_TRACE;
 3537:   return CMD_SUCCESS;
 3538: }
 3539: 
 3540: ALIAS (no_debug_igmp,
 3541:        undebug_igmp_cmd,
 3542:        "undebug igmp",
 3543:        UNDEBUG_STR
 3544:        DEBUG_IGMP_STR)
 3545: 
 3546: DEFUN (debug_igmp_events,
 3547:        debug_igmp_events_cmd,
 3548:        "debug igmp events",
 3549:        DEBUG_STR
 3550:        DEBUG_IGMP_STR
 3551:        DEBUG_IGMP_EVENTS_STR)
 3552: {
 3553:   PIM_DO_DEBUG_IGMP_EVENTS;
 3554:   return CMD_SUCCESS;
 3555: }
 3556: 
 3557: DEFUN (no_debug_igmp_events,
 3558:        no_debug_igmp_events_cmd,
 3559:        "no debug igmp events",
 3560:        NO_STR
 3561:        DEBUG_STR
 3562:        DEBUG_IGMP_STR
 3563:        DEBUG_IGMP_EVENTS_STR)
 3564: {
 3565:   PIM_DONT_DEBUG_IGMP_EVENTS;
 3566:   return CMD_SUCCESS;
 3567: }
 3568: 
 3569: ALIAS (no_debug_igmp_events,
 3570:        undebug_igmp_events_cmd,
 3571:        "undebug igmp events",
 3572:        UNDEBUG_STR
 3573:        DEBUG_IGMP_STR
 3574:        DEBUG_IGMP_EVENTS_STR)
 3575: 
 3576: DEFUN (debug_igmp_packets,
 3577:        debug_igmp_packets_cmd,
 3578:        "debug igmp packets",
 3579:        DEBUG_STR
 3580:        DEBUG_IGMP_STR
 3581:        DEBUG_IGMP_PACKETS_STR)
 3582: {
 3583:   PIM_DO_DEBUG_IGMP_PACKETS;
 3584:   return CMD_SUCCESS;
 3585: }
 3586: 
 3587: DEFUN (no_debug_igmp_packets,
 3588:        no_debug_igmp_packets_cmd,
 3589:        "no debug igmp packets",
 3590:        NO_STR
 3591:        DEBUG_STR
 3592:        DEBUG_IGMP_STR
 3593:        DEBUG_IGMP_PACKETS_STR)
 3594: {
 3595:   PIM_DONT_DEBUG_IGMP_PACKETS;
 3596:   return CMD_SUCCESS;
 3597: }
 3598: 
 3599: ALIAS (no_debug_igmp_packets,
 3600:        undebug_igmp_packets_cmd,
 3601:        "undebug igmp packets",
 3602:        UNDEBUG_STR
 3603:        DEBUG_IGMP_STR
 3604:        DEBUG_IGMP_PACKETS_STR)
 3605: 
 3606: DEFUN (debug_igmp_trace,
 3607:        debug_igmp_trace_cmd,
 3608:        "debug igmp trace",
 3609:        DEBUG_STR
 3610:        DEBUG_IGMP_STR
 3611:        DEBUG_IGMP_TRACE_STR)
 3612: {
 3613:   PIM_DO_DEBUG_IGMP_TRACE;
 3614:   return CMD_SUCCESS;
 3615: }
 3616: 
 3617: DEFUN (no_debug_igmp_trace,
 3618:        no_debug_igmp_trace_cmd,
 3619:        "no debug igmp trace",
 3620:        NO_STR
 3621:        DEBUG_STR
 3622:        DEBUG_IGMP_STR
 3623:        DEBUG_IGMP_TRACE_STR)
 3624: {
 3625:   PIM_DONT_DEBUG_IGMP_TRACE;
 3626:   return CMD_SUCCESS;
 3627: }
 3628: 
 3629: ALIAS (no_debug_igmp_trace,
 3630:        undebug_igmp_trace_cmd,
 3631:        "undebug igmp trace",
 3632:        UNDEBUG_STR
 3633:        DEBUG_IGMP_STR
 3634:        DEBUG_IGMP_TRACE_STR)
 3635: 
 3636: DEFUN (debug_mroute,
 3637:        debug_mroute_cmd,
 3638:        "debug mroute",
 3639:        DEBUG_STR
 3640:        DEBUG_MROUTE_STR)
 3641: {
 3642:   PIM_DO_DEBUG_MROUTE;
 3643:   return CMD_SUCCESS;
 3644: }
 3645: 
 3646: DEFUN (no_debug_mroute,
 3647:        no_debug_mroute_cmd,
 3648:        "no debug mroute",
 3649:        NO_STR
 3650:        DEBUG_STR
 3651:        DEBUG_MROUTE_STR)
 3652: {
 3653:   PIM_DONT_DEBUG_MROUTE;
 3654:   return CMD_SUCCESS;
 3655: }
 3656: 
 3657: ALIAS (no_debug_mroute,
 3658:        undebug_mroute_cmd,
 3659:        "undebug mroute",
 3660:        UNDEBUG_STR
 3661:        DEBUG_MROUTE_STR)
 3662: 
 3663: DEFUN (debug_static,
 3664:        debug_static_cmd,
 3665:        "debug static",
 3666:        DEBUG_STR
 3667:        DEBUG_STATIC_STR)
 3668: {
 3669:   PIM_DO_DEBUG_STATIC;
 3670:   return CMD_SUCCESS;
 3671: }
 3672: 
 3673: DEFUN (no_debug_static,
 3674:        no_debug_static_cmd,
 3675:        "no debug static",
 3676:        NO_STR
 3677:        DEBUG_STR
 3678:        DEBUG_STATIC_STR)
 3679: {
 3680:   PIM_DONT_DEBUG_STATIC;
 3681:   return CMD_SUCCESS;
 3682: }
 3683: 
 3684: ALIAS (no_debug_static,
 3685:        undebug_static_cmd,
 3686:        "undebug static",
 3687:        UNDEBUG_STR
 3688:        DEBUG_STATIC_STR)
 3689: 
 3690: DEFUN (debug_pim,
 3691:        debug_pim_cmd,
 3692:        "debug pim",
 3693:        DEBUG_STR
 3694:        DEBUG_PIM_STR)
 3695: {
 3696:   PIM_DO_DEBUG_PIM_EVENTS;
 3697:   PIM_DO_DEBUG_PIM_PACKETS;
 3698:   PIM_DO_DEBUG_PIM_TRACE;
 3699:   return CMD_SUCCESS;
 3700: }
 3701: 
 3702: DEFUN (no_debug_pim,
 3703:        no_debug_pim_cmd,
 3704:        "no debug pim",
 3705:        NO_STR
 3706:        DEBUG_STR
 3707:        DEBUG_PIM_STR)
 3708: {
 3709:   PIM_DONT_DEBUG_PIM_EVENTS;
 3710:   PIM_DONT_DEBUG_PIM_PACKETS;
 3711:   PIM_DONT_DEBUG_PIM_TRACE;
 3712: 
 3713:   PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
 3714:   PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
 3715: 
 3716:   return CMD_SUCCESS;
 3717: }
 3718: 
 3719: ALIAS (no_debug_pim,
 3720:        undebug_pim_cmd,
 3721:        "undebug pim",
 3722:        UNDEBUG_STR
 3723:        DEBUG_PIM_STR)
 3724: 
 3725: DEFUN (debug_pim_events,
 3726:        debug_pim_events_cmd,
 3727:        "debug pim events",
 3728:        DEBUG_STR
 3729:        DEBUG_PIM_STR
 3730:        DEBUG_PIM_EVENTS_STR)
 3731: {
 3732:   PIM_DO_DEBUG_PIM_EVENTS;
 3733:   return CMD_SUCCESS;
 3734: }
 3735: 
 3736: DEFUN (no_debug_pim_events,
 3737:        no_debug_pim_events_cmd,
 3738:        "no debug pim events",
 3739:        NO_STR
 3740:        DEBUG_STR
 3741:        DEBUG_PIM_STR
 3742:        DEBUG_PIM_EVENTS_STR)
 3743: {
 3744:   PIM_DONT_DEBUG_PIM_EVENTS;
 3745:   return CMD_SUCCESS;
 3746: }
 3747: 
 3748: ALIAS (no_debug_pim_events,
 3749:        undebug_pim_events_cmd,
 3750:        "undebug pim events",
 3751:        UNDEBUG_STR
 3752:        DEBUG_PIM_STR
 3753:        DEBUG_PIM_EVENTS_STR)
 3754: 
 3755: DEFUN (debug_pim_packets,
 3756:        debug_pim_packets_cmd,
 3757:        "debug pim packets",
 3758:        DEBUG_STR
 3759:        DEBUG_PIM_STR
 3760:        DEBUG_PIM_PACKETS_STR)
 3761: {
 3762:     PIM_DO_DEBUG_PIM_PACKETS;
 3763:     vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
 3764:     return CMD_SUCCESS;
 3765: }
 3766: 
 3767: DEFUN (debug_pim_packets_filter,
 3768:        debug_pim_packets_filter_cmd,
 3769:        "debug pim packets (hello|joins)",
 3770:        DEBUG_STR
 3771:        DEBUG_PIM_STR
 3772:        DEBUG_PIM_PACKETS_STR
 3773:        DEBUG_PIM_HELLO_PACKETS_STR
 3774:        DEBUG_PIM_J_P_PACKETS_STR)
 3775: {
 3776:     if (strncmp(argv[0],"h",1) == 0) 
 3777:     {
 3778:       PIM_DO_DEBUG_PIM_HELLO;
 3779:       vty_out (vty, "PIM Hello debugging is on %s", VTY_NEWLINE);
 3780:     }
 3781:     else if (strncmp(argv[0],"j",1) == 0)
 3782:     {
 3783:       PIM_DO_DEBUG_PIM_J_P;
 3784:       vty_out (vty, "PIM Join/Prune debugging is on %s", VTY_NEWLINE);
 3785:     }
 3786:   return CMD_SUCCESS;
 3787: }
 3788: 
 3789: DEFUN (no_debug_pim_packets,
 3790:        no_debug_pim_packets_cmd,
 3791:        "no debug pim packets",
 3792:        NO_STR
 3793:        DEBUG_STR
 3794:        DEBUG_PIM_STR
 3795:        DEBUG_PIM_PACKETS_STR
 3796:        DEBUG_PIM_HELLO_PACKETS_STR
 3797:        DEBUG_PIM_J_P_PACKETS_STR)
 3798: {
 3799:   PIM_DONT_DEBUG_PIM_PACKETS;
 3800:   vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
 3801:   return CMD_SUCCESS;
 3802: }
 3803: 
 3804: DEFUN (no_debug_pim_packets_filter,
 3805:        no_debug_pim_packets_filter_cmd,
 3806:        "no debug pim packets (hello|joins)",
 3807:        NO_STR
 3808:        DEBUG_STR
 3809:        DEBUG_PIM_STR
 3810:        DEBUG_PIM_PACKETS_STR
 3811:        DEBUG_PIM_HELLO_PACKETS_STR
 3812:        DEBUG_PIM_J_P_PACKETS_STR)
 3813: {
 3814:     if (strncmp(argv[0],"h",1) == 0) 
 3815:     {
 3816:       PIM_DONT_DEBUG_PIM_HELLO;
 3817:       vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
 3818:     }
 3819:     else if (strncmp(argv[0],"j",1) == 0)
 3820:     {
 3821:       PIM_DONT_DEBUG_PIM_J_P;
 3822:       vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
 3823:     }
 3824:     return CMD_SUCCESS;
 3825: }
 3826: 
 3827: ALIAS (no_debug_pim_packets,
 3828:        undebug_pim_packets_cmd,
 3829:        "undebug pim packets",
 3830:        UNDEBUG_STR
 3831:        DEBUG_PIM_STR
 3832:        DEBUG_PIM_PACKETS_STR)
 3833: 
 3834: DEFUN (debug_pim_packetdump_send,
 3835:        debug_pim_packetdump_send_cmd,
 3836:        "debug pim packet-dump send",
 3837:        DEBUG_STR
 3838:        DEBUG_PIM_STR
 3839:        DEBUG_PIM_PACKETDUMP_STR
 3840:        DEBUG_PIM_PACKETDUMP_SEND_STR)
 3841: {
 3842:   PIM_DO_DEBUG_PIM_PACKETDUMP_SEND;
 3843:   return CMD_SUCCESS;
 3844: }
 3845: 
 3846: DEFUN (no_debug_pim_packetdump_send,
 3847:        no_debug_pim_packetdump_send_cmd,
 3848:        "no debug pim packet-dump send",
 3849:        NO_STR
 3850:        DEBUG_STR
 3851:        DEBUG_PIM_STR
 3852:        DEBUG_PIM_PACKETDUMP_STR
 3853:        DEBUG_PIM_PACKETDUMP_SEND_STR)
 3854: {
 3855:   PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND;
 3856:   return CMD_SUCCESS;
 3857: }
 3858: 
 3859: ALIAS (no_debug_pim_packetdump_send,
 3860:        undebug_pim_packetdump_send_cmd,
 3861:        "undebug pim packet-dump send",
 3862:        UNDEBUG_STR
 3863:        DEBUG_PIM_STR
 3864:        DEBUG_PIM_PACKETDUMP_STR
 3865:        DEBUG_PIM_PACKETDUMP_SEND_STR)
 3866: 
 3867: DEFUN (debug_pim_packetdump_recv,
 3868:        debug_pim_packetdump_recv_cmd,
 3869:        "debug pim packet-dump receive",
 3870:        DEBUG_STR
 3871:        DEBUG_PIM_STR
 3872:        DEBUG_PIM_PACKETDUMP_STR
 3873:        DEBUG_PIM_PACKETDUMP_RECV_STR)
 3874: {
 3875:   PIM_DO_DEBUG_PIM_PACKETDUMP_RECV;
 3876:   return CMD_SUCCESS;
 3877: }
 3878: 
 3879: DEFUN (no_debug_pim_packetdump_recv,
 3880:        no_debug_pim_packetdump_recv_cmd,
 3881:        "no debug pim packet-dump receive",
 3882:        NO_STR
 3883:        DEBUG_STR
 3884:        DEBUG_PIM_STR
 3885:        DEBUG_PIM_PACKETDUMP_STR
 3886:        DEBUG_PIM_PACKETDUMP_RECV_STR)
 3887: {
 3888:   PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV;
 3889:   return CMD_SUCCESS;
 3890: }
 3891: 
 3892: ALIAS (no_debug_pim_packetdump_recv,
 3893:        undebug_pim_packetdump_recv_cmd,
 3894:        "undebug pim packet-dump receive",
 3895:        UNDEBUG_STR
 3896:        DEBUG_PIM_STR
 3897:        DEBUG_PIM_PACKETDUMP_STR
 3898:        DEBUG_PIM_PACKETDUMP_RECV_STR)
 3899: 
 3900: DEFUN (debug_pim_trace,
 3901:        debug_pim_trace_cmd,
 3902:        "debug pim trace",
 3903:        DEBUG_STR
 3904:        DEBUG_PIM_STR
 3905:        DEBUG_PIM_TRACE_STR)
 3906: {
 3907:   PIM_DO_DEBUG_PIM_TRACE;
 3908:   return CMD_SUCCESS;
 3909: }
 3910: 
 3911: DEFUN (no_debug_pim_trace,
 3912:        no_debug_pim_trace_cmd,
 3913:        "no debug pim trace",
 3914:        NO_STR
 3915:        DEBUG_STR
 3916:        DEBUG_PIM_STR
 3917:        DEBUG_PIM_TRACE_STR)
 3918: {
 3919:   PIM_DONT_DEBUG_PIM_TRACE;
 3920:   return CMD_SUCCESS;
 3921: }
 3922: 
 3923: ALIAS (no_debug_pim_trace,
 3924:        undebug_pim_trace_cmd,
 3925:        "undebug pim trace",
 3926:        UNDEBUG_STR
 3927:        DEBUG_PIM_STR
 3928:        DEBUG_PIM_TRACE_STR)
 3929: 
 3930: DEFUN (debug_ssmpingd,
 3931:        debug_ssmpingd_cmd,
 3932:        "debug ssmpingd",
 3933:        DEBUG_STR
 3934:        DEBUG_PIM_STR
 3935:        DEBUG_SSMPINGD_STR)
 3936: {
 3937:   PIM_DO_DEBUG_SSMPINGD;
 3938:   return CMD_SUCCESS;
 3939: }
 3940: 
 3941: DEFUN (no_debug_ssmpingd,
 3942:        no_debug_ssmpingd_cmd,
 3943:        "no debug ssmpingd",
 3944:        NO_STR
 3945:        DEBUG_STR
 3946:        DEBUG_PIM_STR
 3947:        DEBUG_SSMPINGD_STR)
 3948: {
 3949:   PIM_DONT_DEBUG_SSMPINGD;
 3950:   return CMD_SUCCESS;
 3951: }
 3952: 
 3953: ALIAS (no_debug_ssmpingd,
 3954:        undebug_ssmpingd_cmd,
 3955:        "undebug ssmpingd",
 3956:        UNDEBUG_STR
 3957:        DEBUG_PIM_STR
 3958:        DEBUG_SSMPINGD_STR)
 3959: 
 3960: DEFUN (debug_pim_zebra,
 3961:        debug_pim_zebra_cmd,
 3962:        "debug pim zebra",
 3963:        DEBUG_STR
 3964:        DEBUG_PIM_STR
 3965:        DEBUG_PIM_ZEBRA_STR)
 3966: {
 3967:   PIM_DO_DEBUG_ZEBRA;
 3968:   return CMD_SUCCESS;
 3969: }
 3970: 
 3971: DEFUN (no_debug_pim_zebra,
 3972:        no_debug_pim_zebra_cmd,
 3973:        "no debug pim zebra",
 3974:        NO_STR
 3975:        DEBUG_STR
 3976:        DEBUG_PIM_STR
 3977:        DEBUG_PIM_ZEBRA_STR)
 3978: {
 3979:   PIM_DONT_DEBUG_ZEBRA;
 3980:   return CMD_SUCCESS;
 3981: }
 3982: 
 3983: ALIAS (no_debug_pim_zebra,
 3984:        undebug_pim_zebra_cmd,
 3985:        "undebug pim zebra",
 3986:        UNDEBUG_STR
 3987:        DEBUG_PIM_STR
 3988:        DEBUG_PIM_ZEBRA_STR)
 3989: 
 3990: DEFUN (show_debugging_pim,
 3991:        show_debugging_pim_cmd,
 3992:        "show debugging pim",
 3993:        SHOW_STR
 3994:        DEBUG_STR
 3995:        PIM_STR)
 3996: {
 3997:   pim_debug_config_write(vty);
 3998:   return CMD_SUCCESS;
 3999: }
 4000: 
 4001: static struct igmp_sock *find_igmp_sock_by_fd(int fd)
 4002: {
 4003:   struct listnode  *ifnode;
 4004:   struct interface *ifp;
 4005: 
 4006:   /* scan all interfaces */
 4007:   for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
 4008:     struct pim_interface *pim_ifp;
 4009:     struct igmp_sock     *igmp;
 4010:     
 4011:     if (!ifp->info)
 4012:       continue;
 4013: 
 4014:     pim_ifp = ifp->info;
 4015: 
 4016:     /* lookup igmp socket under current interface */
 4017:     igmp = igmp_sock_lookup_by_fd(pim_ifp->igmp_socket_list, fd);
 4018:     if (igmp)
 4019:       return igmp;
 4020:   }
 4021: 
 4022:   return 0;
 4023: }
 4024: 
 4025: DEFUN (test_igmp_receive_report,
 4026:        test_igmp_receive_report_cmd,
 4027:        "test igmp receive report <0-65535> A.B.C.D <1-6> .LINE",
 4028:        "Test\n"
 4029:        "Test IGMP protocol\n"
 4030:        "Test IGMP message\n"
 4031:        "Test IGMP report\n"
 4032:        "Socket\n"
 4033:        "IGMP group address\n"
 4034:        "Record type\n"
 4035:        "Sources\n")
 4036: {
 4037:   char              buf[1000];
 4038:   char             *igmp_msg;
 4039:   struct ip        *ip_hdr;
 4040:   size_t            ip_hlen; /* ip header length in bytes */
 4041:   int               ip_msg_len;
 4042:   int               igmp_msg_len;
 4043:   const char       *socket;
 4044:   int               socket_fd;
 4045:   const char       *grp_str;
 4046:   struct in_addr    grp_addr;
 4047:   const char       *record_type_str;
 4048:   int               record_type;
 4049:   const char       *src_str;
 4050:   int               result;
 4051:   struct igmp_sock *igmp;
 4052:   char             *group_record;
 4053:   int               num_sources;
 4054:   struct in_addr   *sources;
 4055:   struct in_addr   *src_addr;
 4056:   int               argi;
 4057: 
 4058:   socket = argv[0];
 4059:   socket_fd = atoi(socket);
 4060:   igmp = find_igmp_sock_by_fd(socket_fd);
 4061:   if (!igmp) {
 4062:     vty_out(vty, "Could not find IGMP socket %s: fd=%d%s",
 4063: 	    socket, socket_fd, VTY_NEWLINE);
 4064:     return CMD_WARNING;
 4065:   }
 4066: 
 4067:   grp_str = argv[1];
 4068:   result = inet_pton(AF_INET, grp_str, &grp_addr);
 4069:   if (result <= 0) {
 4070:     vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 4071: 	    grp_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4072:     return CMD_WARNING;
 4073:   }
 4074: 
 4075:   record_type_str = argv[2];
 4076:   record_type = atoi(record_type_str);
 4077: 
 4078:   /*
 4079:     Tweak IP header
 4080:    */
 4081:   ip_hdr = (struct ip *) buf;
 4082:   ip_hdr->ip_p = PIM_IP_PROTO_IGMP;
 4083:   ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
 4084:   ip_hdr->ip_hl = ip_hlen >> 2;    /* ip header length in 4-byte words */
 4085:   ip_hdr->ip_src = igmp->ifaddr;
 4086:   ip_hdr->ip_dst = igmp->ifaddr;
 4087: 
 4088:   /*
 4089:     Build IGMP v3 report message
 4090:    */
 4091:   igmp_msg = buf + ip_hlen;
 4092:   group_record = igmp_msg + IGMP_V3_REPORT_GROUPPRECORD_OFFSET;
 4093:   *igmp_msg = PIM_IGMP_V3_MEMBERSHIP_REPORT; /* type */
 4094:   *(uint16_t *)      (igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = 0; /* for computing checksum */
 4095:   *(uint16_t *)      (igmp_msg + IGMP_V3_REPORT_NUMGROUPS_OFFSET) = htons(1); /* one group record */
 4096:   *(uint8_t  *)      (group_record + IGMP_V3_GROUP_RECORD_TYPE_OFFSET) = record_type;
 4097:   memcpy(group_record + IGMP_V3_GROUP_RECORD_GROUP_OFFSET, &grp_addr, sizeof(struct in_addr));
 4098: 
 4099:   /* Scan LINE sources */
 4100:   sources = (struct in_addr *) (group_record + IGMP_V3_GROUP_RECORD_SOURCE_OFFSET);
 4101:   src_addr = sources;
 4102:   for (argi = 3; argi < argc; ++argi,++src_addr) {
 4103:     src_str = argv[argi];
 4104:     result = inet_pton(AF_INET, src_str, src_addr);
 4105:     if (result <= 0) {
 4106:       vty_out(vty, "Bad source address %s: errno=%d: %s%s",
 4107: 	      src_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4108:       return CMD_WARNING;
 4109:     }
 4110:   }
 4111:   num_sources = src_addr - sources;
 4112: 
 4113:   *(uint16_t *)(group_record + IGMP_V3_GROUP_RECORD_NUMSOURCES_OFFSET) = htons(num_sources);
 4114: 
 4115:   igmp_msg_len = IGMP_V3_MSG_MIN_SIZE + (num_sources << 4);   /* v3 report for one single group record */
 4116: 
 4117:   /* compute checksum */
 4118:   *(uint16_t *)(igmp_msg + IGMP_V3_CHECKSUM_OFFSET) = in_cksum(igmp_msg, igmp_msg_len);
 4119: 
 4120:   /* "receive" message */
 4121: 
 4122:   ip_msg_len = ip_hlen + igmp_msg_len;
 4123:   result = pim_igmp_packet(igmp, buf, ip_msg_len);
 4124:   if (result) {
 4125:     vty_out(vty, "pim_igmp_packet(len=%d) returned: %d%s",
 4126: 	    ip_msg_len, result, VTY_NEWLINE);
 4127:     return CMD_WARNING;
 4128:   }
 4129: 
 4130:   return CMD_SUCCESS;
 4131: }
 4132: 
 4133: static int hexval(uint8_t ch)
 4134: {
 4135:   return isdigit(ch) ? (ch - '0') : (10 + tolower(ch) - 'a');
 4136: }
 4137: 
 4138: DEFUN (test_pim_receive_dump,
 4139:        test_pim_receive_dump_cmd,
 4140:        "test pim receive dump INTERFACE A.B.C.D .LINE",
 4141:        "Test\n"
 4142:        "Test PIM protocol\n"
 4143:        "Test PIM message reception\n"
 4144:        "Test PIM packet dump reception from neighbor\n"
 4145:        "Interface\n"
 4146:        "Neighbor address\n"
 4147:        "Packet dump\n")
 4148: {
 4149:   uint8_t           buf[1000];
 4150:   uint8_t          *pim_msg;
 4151:   struct ip        *ip_hdr;
 4152:   size_t            ip_hlen; /* ip header length in bytes */
 4153:   int               ip_msg_len;
 4154:   int               pim_msg_size;
 4155:   const char       *neigh_str;
 4156:   struct in_addr    neigh_addr;
 4157:   const char       *ifname;
 4158:   struct interface *ifp;
 4159:   int               argi;
 4160:   int               result;
 4161: 
 4162:   /* Find interface */
 4163:   ifname = argv[0];
 4164:   ifp = if_lookup_by_name(ifname);
 4165:   if (!ifp) {
 4166:     vty_out(vty, "No such interface name %s%s",
 4167: 	    ifname, VTY_NEWLINE);
 4168:     return CMD_WARNING;
 4169:   }
 4170: 
 4171:   /* Neighbor address */
 4172:   neigh_str = argv[1];
 4173:   result = inet_pton(AF_INET, neigh_str, &neigh_addr);
 4174:   if (result <= 0) {
 4175:     vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
 4176: 	    neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4177:     return CMD_WARNING;
 4178:   }
 4179: 
 4180:   /*
 4181:     Tweak IP header
 4182:    */
 4183:   ip_hdr = (struct ip *) buf;
 4184:   ip_hdr->ip_p = PIM_IP_PROTO_PIM;
 4185:   ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
 4186:   ip_hdr->ip_hl = ip_hlen >> 2;    /* ip header length in 4-byte words */
 4187:   ip_hdr->ip_src = neigh_addr;
 4188:   ip_hdr->ip_dst = qpim_all_pim_routers_addr;
 4189: 
 4190:   /*
 4191:     Build PIM hello message
 4192:   */
 4193:   pim_msg = buf + ip_hlen;
 4194:   pim_msg_size = 0;
 4195: 
 4196:   /* Scan LINE dump into buffer */
 4197:   for (argi = 2; argi < argc; ++argi) {
 4198:     const char *str = argv[argi];
 4199:     int str_len = strlen(str);
 4200:     int str_last = str_len - 1;
 4201:     int i;
 4202: 
 4203:     if (str_len % 2) {
 4204:       vty_out(vty, "%% Uneven hex array arg %d=%s%s",
 4205: 	      argi, str, VTY_NEWLINE);
 4206:       return CMD_WARNING;
 4207:     }
 4208: 
 4209:     for (i = 0; i < str_last; i += 2) {
 4210:       uint8_t octet;
 4211:       int left;
 4212:       uint8_t h1 = str[i];
 4213:       uint8_t h2 = str[i + 1];
 4214: 
 4215:       if (!isxdigit(h1) || !isxdigit(h2)) {
 4216: 	vty_out(vty, "%% Non-hex octet %c%c at hex array arg %d=%s%s",
 4217: 		h1, h2, argi, str, VTY_NEWLINE);
 4218: 	return CMD_WARNING;
 4219:       }
 4220:       octet = (hexval(h1) << 4) + hexval(h2);
 4221: 
 4222:       left = sizeof(buf) - ip_hlen - pim_msg_size;
 4223:       if (left < 1) {
 4224: 	vty_out(vty, "%% Overflow buf_size=%zu buf_left=%d at hex array arg %d=%s octet %02x%s",
 4225: 		sizeof(buf), left, argi, str, octet, VTY_NEWLINE);
 4226: 	return CMD_WARNING;
 4227:       }
 4228:       
 4229:       pim_msg[pim_msg_size++] = octet;
 4230:     }
 4231:   }
 4232: 
 4233:   ip_msg_len = ip_hlen + pim_msg_size;
 4234: 
 4235:   vty_out(vty, "Receiving: buf_size=%zu ip_msg_size=%d pim_msg_size=%d%s",
 4236: 	  sizeof(buf), ip_msg_len, pim_msg_size, VTY_NEWLINE);
 4237: 
 4238:   /* "receive" message */
 4239: 
 4240:   result = pim_pim_packet(ifp, buf, ip_msg_len);
 4241:   if (result) {
 4242:     vty_out(vty, "%% pim_pim_packet(len=%d) returned failure: %d%s",
 4243: 	    ip_msg_len, result, VTY_NEWLINE);
 4244:     return CMD_WARNING;
 4245:   }
 4246: 
 4247:   return CMD_SUCCESS;
 4248: }
 4249: 
 4250: DEFUN (test_pim_receive_hello,
 4251:        test_pim_receive_hello_cmd,
 4252:        "test pim receive hello INTERFACE A.B.C.D <0-65535> <0-65535> <0-65535> <0-32767> <0-65535> <0-1>[LINE]",
 4253:        "Test\n"
 4254:        "Test PIM protocol\n"
 4255:        "Test PIM message reception\n"
 4256:        "Test PIM hello reception from neighbor\n"
 4257:        "Interface\n"
 4258:        "Neighbor address\n"
 4259:        "Neighbor holdtime\n"
 4260:        "Neighbor DR priority\n"
 4261:        "Neighbor generation ID\n"
 4262:        "Neighbor propagation delay (msec)\n"
 4263:        "Neighbor override interval (msec)\n"
 4264:        "Neighbor LAN prune delay T-bit\n"
 4265:        "Neighbor secondary addresses\n")
 4266: {
 4267:   uint8_t           buf[1000];
 4268:   uint8_t          *pim_msg;
 4269:   struct ip        *ip_hdr;
 4270:   size_t            ip_hlen; /* ip header length in bytes */
 4271:   int               ip_msg_len;
 4272:   int               pim_tlv_size;
 4273:   int               pim_msg_size;
 4274:   const char       *neigh_str;
 4275:   struct in_addr    neigh_addr;
 4276:   const char       *ifname;
 4277:   struct interface *ifp;
 4278:   uint16_t          neigh_holdtime;
 4279:   uint16_t          neigh_propagation_delay;
 4280:   uint16_t          neigh_override_interval;
 4281:   int               neigh_can_disable_join_suppression;
 4282:   uint32_t          neigh_dr_priority;
 4283:   uint32_t          neigh_generation_id;
 4284:   int               argi;
 4285:   int               result;
 4286: 
 4287:   /* Find interface */
 4288:   ifname = argv[0];
 4289:   ifp = if_lookup_by_name(ifname);
 4290:   if (!ifp) {
 4291:     vty_out(vty, "No such interface name %s%s",
 4292: 	    ifname, VTY_NEWLINE);
 4293:     return CMD_WARNING;
 4294:   }
 4295: 
 4296:   /* Neighbor address */
 4297:   neigh_str = argv[1];
 4298:   result = inet_pton(AF_INET, neigh_str, &neigh_addr);
 4299:   if (result <= 0) {
 4300:     vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
 4301: 	    neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4302:     return CMD_WARNING;
 4303:   }
 4304: 
 4305:   neigh_holdtime                     = atoi(argv[2]);
 4306:   neigh_dr_priority                  = atoi(argv[3]);
 4307:   neigh_generation_id                = atoi(argv[4]);
 4308:   neigh_propagation_delay            = atoi(argv[5]);
 4309:   neigh_override_interval            = atoi(argv[6]);
 4310:   neigh_can_disable_join_suppression = atoi(argv[7]);
 4311: 
 4312:   /*
 4313:     Tweak IP header
 4314:    */
 4315:   ip_hdr = (struct ip *) buf;
 4316:   ip_hdr->ip_p = PIM_IP_PROTO_PIM;
 4317:   ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
 4318:   ip_hdr->ip_hl = ip_hlen >> 2;    /* ip header length in 4-byte words */
 4319:   ip_hdr->ip_src = neigh_addr;
 4320:   ip_hdr->ip_dst = qpim_all_pim_routers_addr;
 4321: 
 4322:   /*
 4323:     Build PIM hello message
 4324:   */
 4325:   pim_msg = buf + ip_hlen;
 4326: 
 4327:   /* Scan LINE addresses */
 4328:   for (argi = 8; argi < argc; ++argi) {
 4329:     const char *sec_str = argv[argi];
 4330:     struct in_addr sec_addr;
 4331:     result = inet_pton(AF_INET, sec_str, &sec_addr);
 4332:     if (result <= 0) {
 4333:       vty_out(vty, "Bad neighbor secondary address %s: errno=%d: %s%s",
 4334: 	      sec_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4335:       return CMD_WARNING;
 4336:     }
 4337: 
 4338:     vty_out(vty,
 4339: 	    "FIXME WRITEME consider neighbor secondary address %s%s",
 4340: 	    sec_str, VTY_NEWLINE);
 4341:   }
 4342: 
 4343:   pim_tlv_size = pim_hello_build_tlv(ifp->name,
 4344: 				     pim_msg + PIM_PIM_MIN_LEN,
 4345: 				     sizeof(buf) - ip_hlen - PIM_PIM_MIN_LEN,
 4346: 				     neigh_holdtime,
 4347: 				     neigh_dr_priority,
 4348: 				     neigh_generation_id,
 4349: 				     neigh_propagation_delay,
 4350: 				     neigh_override_interval,
 4351: 				     neigh_can_disable_join_suppression,
 4352: 				     0 /* FIXME secondary address list */);
 4353:   if (pim_tlv_size < 0) {
 4354:     vty_out(vty, "pim_hello_build_tlv() returned failure: %d%s",
 4355: 	    pim_tlv_size, VTY_NEWLINE);
 4356:     return CMD_WARNING;
 4357:   }
 4358: 
 4359:   pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
 4360: 
 4361:   pim_msg_build_header(pim_msg, pim_msg_size,
 4362: 		       PIM_MSG_TYPE_HELLO);
 4363: 
 4364:   /* "receive" message */
 4365: 
 4366:   ip_msg_len = ip_hlen + pim_msg_size;
 4367:   result = pim_pim_packet(ifp, buf, ip_msg_len);
 4368:   if (result) {
 4369:     vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
 4370: 	    ip_msg_len, result, VTY_NEWLINE);
 4371:     return CMD_WARNING;
 4372:   }
 4373: 
 4374:   return CMD_SUCCESS;
 4375: }
 4376: 
 4377: DEFUN (test_pim_receive_assert,
 4378:        test_pim_receive_assert_cmd,
 4379:        "test pim receive assert INTERFACE A.B.C.D A.B.C.D A.B.C.D <0-65535> <0-65535> <0-1>",
 4380:        "Test\n"
 4381:        "Test PIM protocol\n"
 4382:        "Test PIM message reception\n"
 4383:        "Test reception of PIM assert\n"
 4384:        "Interface\n"
 4385:        "Neighbor address\n"
 4386:        "Assert multicast group address\n"
 4387:        "Assert unicast source address\n"
 4388:        "Assert metric preference\n"
 4389:        "Assert route metric\n"
 4390:        "Assert RPT bit flag\n")
 4391: {
 4392:   uint8_t           buf[1000];
 4393:   uint8_t          *buf_pastend = buf + sizeof(buf);
 4394:   uint8_t          *pim_msg;
 4395:   struct ip        *ip_hdr;
 4396:   size_t            ip_hlen; /* ip header length in bytes */
 4397:   int               ip_msg_len;
 4398:   int               pim_msg_size;
 4399:   const char       *neigh_str;
 4400:   struct in_addr    neigh_addr;
 4401:   const char       *group_str;
 4402:   struct in_addr    group_addr;
 4403:   const char       *source_str;
 4404:   struct in_addr    source_addr;
 4405:   const char       *ifname;
 4406:   struct interface *ifp;
 4407:   uint32_t          assert_metric_preference;
 4408:   uint32_t          assert_route_metric;
 4409:   uint32_t          assert_rpt_bit_flag;
 4410:   int               remain;
 4411:   int               result;
 4412: 
 4413:   /* Find interface */
 4414:   ifname = argv[0];
 4415:   ifp = if_lookup_by_name(ifname);
 4416:   if (!ifp) {
 4417:     vty_out(vty, "No such interface name %s%s",
 4418: 	    ifname, VTY_NEWLINE);
 4419:     return CMD_WARNING;
 4420:   }
 4421: 
 4422:   /* Neighbor address */
 4423:   neigh_str = argv[1];
 4424:   result = inet_pton(AF_INET, neigh_str, &neigh_addr);
 4425:   if (result <= 0) {
 4426:     vty_out(vty, "Bad neighbor address %s: errno=%d: %s%s",
 4427: 	    neigh_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4428:     return CMD_WARNING;
 4429:   }
 4430: 
 4431:   /* Group address */
 4432:   group_str = argv[2];
 4433:   result = inet_pton(AF_INET, group_str, &group_addr);
 4434:   if (result <= 0) {
 4435:     vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 4436: 	    group_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4437:     return CMD_WARNING;
 4438:   }
 4439: 
 4440:   /* Source address */
 4441:   source_str = argv[3];
 4442:   result = inet_pton(AF_INET, source_str, &source_addr);
 4443:   if (result <= 0) {
 4444:     vty_out(vty, "Bad source address %s: errno=%d: %s%s",
 4445: 	    source_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4446:     return CMD_WARNING;
 4447:   }
 4448: 
 4449:   assert_metric_preference = atoi(argv[4]);
 4450:   assert_route_metric      = atoi(argv[5]);
 4451:   assert_rpt_bit_flag      = atoi(argv[6]);
 4452: 
 4453:   remain = buf_pastend - buf;
 4454:   if (remain < (int) sizeof(struct ip)) {
 4455:     vty_out(vty, "No room for ip header: buf_size=%d < ip_header_size=%zu%s",
 4456: 	    remain, sizeof(struct ip), VTY_NEWLINE);
 4457:     return CMD_WARNING;
 4458:   }
 4459: 
 4460:   /*
 4461:     Tweak IP header
 4462:    */
 4463:   ip_hdr = (struct ip *) buf;
 4464:   ip_hdr->ip_p = PIM_IP_PROTO_PIM;
 4465:   ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
 4466:   ip_hdr->ip_hl = ip_hlen >> 2;    /* ip header length in 4-byte words */
 4467:   ip_hdr->ip_src = neigh_addr;
 4468:   ip_hdr->ip_dst = qpim_all_pim_routers_addr;
 4469: 
 4470:   /*
 4471:     Build PIM assert message
 4472:   */
 4473:   pim_msg = buf + ip_hlen; /* skip ip header */
 4474: 
 4475:   pim_msg_size = pim_assert_build_msg(pim_msg, buf_pastend - pim_msg, ifp,
 4476: 				      group_addr, source_addr,
 4477: 				      assert_metric_preference,
 4478: 				      assert_route_metric,
 4479: 				      assert_rpt_bit_flag);
 4480:   if (pim_msg_size < 0) {
 4481:     vty_out(vty, "Failure building PIM assert message: size=%d%s",
 4482: 	    pim_msg_size, VTY_NEWLINE);
 4483:     return CMD_WARNING;
 4484:   }
 4485: 
 4486:   /* "receive" message */
 4487: 
 4488:   ip_msg_len = ip_hlen + pim_msg_size;
 4489:   result = pim_pim_packet(ifp, buf, ip_msg_len);
 4490:   if (result) {
 4491:     vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
 4492: 	    ip_msg_len, result, VTY_NEWLINE);
 4493:     return CMD_WARNING;
 4494:   }
 4495: 
 4496:   return CMD_SUCCESS;
 4497: }
 4498: 
 4499: static int recv_joinprune(struct vty *vty,
 4500: 			  const char *argv[],
 4501: 			  int src_is_join)
 4502: {
 4503:   uint8_t           buf[1000];
 4504:   const uint8_t    *buf_pastend = buf + sizeof(buf);
 4505:   uint8_t          *pim_msg;
 4506:   uint8_t          *pim_msg_curr;
 4507:   int               pim_msg_size;
 4508:   struct ip        *ip_hdr;
 4509:   size_t            ip_hlen; /* ip header length in bytes */
 4510:   int               ip_msg_len;
 4511:   uint16_t          neigh_holdtime;
 4512:   const char       *neigh_dst_str;
 4513:   struct in_addr    neigh_dst_addr;
 4514:   const char       *neigh_src_str;
 4515:   struct in_addr    neigh_src_addr;
 4516:   const char       *group_str;
 4517:   struct in_addr    group_addr;
 4518:   const char       *source_str;
 4519:   struct in_addr    source_addr;
 4520:   const char       *ifname;
 4521:   struct interface *ifp;
 4522:   int               result;
 4523:   int               remain;
 4524:   uint16_t          num_joined;
 4525:   uint16_t          num_pruned;
 4526: 
 4527:   /* Find interface */
 4528:   ifname = argv[0];
 4529:   ifp = if_lookup_by_name(ifname);
 4530:   if (!ifp) {
 4531:     vty_out(vty, "No such interface name %s%s",
 4532: 	    ifname, VTY_NEWLINE);
 4533:     return CMD_WARNING;
 4534:   }
 4535: 
 4536:   neigh_holdtime = atoi(argv[1]);
 4537: 
 4538:   /* Neighbor destination address */
 4539:   neigh_dst_str = argv[2];
 4540:   result = inet_pton(AF_INET, neigh_dst_str, &neigh_dst_addr);
 4541:   if (result <= 0) {
 4542:     vty_out(vty, "Bad neighbor destination address %s: errno=%d: %s%s",
 4543: 	    neigh_dst_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4544:     return CMD_WARNING;
 4545:   }
 4546: 
 4547:   /* Neighbor source address */
 4548:   neigh_src_str = argv[3];
 4549:   result = inet_pton(AF_INET, neigh_src_str, &neigh_src_addr);
 4550:   if (result <= 0) {
 4551:     vty_out(vty, "Bad neighbor source address %s: errno=%d: %s%s",
 4552: 	    neigh_src_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4553:     return CMD_WARNING;
 4554:   }
 4555: 
 4556:   /* Multicast group address */
 4557:   group_str = argv[4];
 4558:   result = inet_pton(AF_INET, group_str, &group_addr);
 4559:   if (result <= 0) {
 4560:     vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 4561: 	    group_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4562:     return CMD_WARNING;
 4563:   }
 4564: 
 4565:   /* Multicast source address */
 4566:   source_str = argv[5];
 4567:   result = inet_pton(AF_INET, source_str, &source_addr);
 4568:   if (result <= 0) {
 4569:     vty_out(vty, "Bad source address %s: errno=%d: %s%s",
 4570: 	    source_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4571:     return CMD_WARNING;
 4572:   }
 4573: 
 4574:   /*
 4575:     Tweak IP header
 4576:    */
 4577:   ip_hdr = (struct ip *) buf;
 4578:   ip_hdr->ip_p = PIM_IP_PROTO_PIM;
 4579:   ip_hlen = PIM_IP_HEADER_MIN_LEN; /* ip header length in bytes */
 4580:   ip_hdr->ip_hl = ip_hlen >> 2;    /* ip header length in 4-byte words */
 4581:   ip_hdr->ip_src = neigh_src_addr;
 4582:   ip_hdr->ip_dst = qpim_all_pim_routers_addr;
 4583: 
 4584:   /*
 4585:     Build PIM message
 4586:   */
 4587:   pim_msg = buf + ip_hlen;
 4588: 
 4589:   /* skip room for pim header */
 4590:   pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN;
 4591: 
 4592:   remain = buf_pastend - pim_msg_curr;
 4593:   pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
 4594: 						remain,
 4595: 						neigh_dst_addr);
 4596:   if (!pim_msg_curr) {
 4597:     vty_out(vty, "Failure encoding destination address %s: space left=%d%s",
 4598: 	    neigh_dst_str, remain, VTY_NEWLINE);
 4599:     return CMD_WARNING;
 4600:   }
 4601: 
 4602:   remain = buf_pastend - pim_msg_curr;
 4603:   if (remain < 4) {
 4604:     vty_out(vty, "Group will not fit: space left=%d%s",
 4605: 	    remain, VTY_NEWLINE);
 4606:     return CMD_WARNING;
 4607:   }
 4608: 
 4609:   *pim_msg_curr = 0; /* reserved */
 4610:   ++pim_msg_curr;
 4611:   *pim_msg_curr = 1; /* number of groups */
 4612:   ++pim_msg_curr;
 4613:   *((uint16_t *) pim_msg_curr) = htons(neigh_holdtime);
 4614:   ++pim_msg_curr;
 4615:   ++pim_msg_curr;
 4616: 
 4617:   remain = buf_pastend - pim_msg_curr;
 4618:   pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
 4619: 						remain,
 4620: 						group_addr);
 4621:   if (!pim_msg_curr) {
 4622:     vty_out(vty, "Failure encoding group address %s: space left=%d%s",
 4623: 	    group_str, remain, VTY_NEWLINE);
 4624:     return CMD_WARNING;
 4625:   }
 4626: 
 4627:   remain = buf_pastend - pim_msg_curr;
 4628:   if (remain < 4) {
 4629:     vty_out(vty, "Sources will not fit: space left=%d%s",
 4630: 	    remain, VTY_NEWLINE);
 4631:     return CMD_WARNING;
 4632:   }
 4633: 
 4634:   if (src_is_join) {
 4635:     num_joined = 1;
 4636:     num_pruned = 0;
 4637:   }
 4638:   else {
 4639:     num_joined = 0;
 4640:     num_pruned = 1;
 4641:   }
 4642: 
 4643:   /* number of joined sources */
 4644:   *((uint16_t *) pim_msg_curr) = htons(num_joined);
 4645:   ++pim_msg_curr;
 4646:   ++pim_msg_curr;
 4647: 
 4648:   /* number of pruned sources */
 4649:   *((uint16_t *) pim_msg_curr) = htons(num_pruned);
 4650:   ++pim_msg_curr;
 4651:   ++pim_msg_curr;
 4652: 
 4653:   remain = buf_pastend - pim_msg_curr;
 4654:   pim_msg_curr = pim_msg_addr_encode_ipv4_source(pim_msg_curr,
 4655: 						 remain,
 4656: 						 source_addr);
 4657:   if (!pim_msg_curr) {
 4658:     vty_out(vty, "Failure encoding source address %s: space left=%d%s",
 4659: 	    source_str, remain, VTY_NEWLINE);
 4660:     return CMD_WARNING;
 4661:   }
 4662: 
 4663:   /* Add PIM header */
 4664: 
 4665:   pim_msg_size = pim_msg_curr - pim_msg;
 4666: 
 4667:   pim_msg_build_header(pim_msg, pim_msg_size,
 4668: 		       PIM_MSG_TYPE_JOIN_PRUNE);
 4669: 
 4670:   /*
 4671:     "Receive" message
 4672:   */
 4673: 
 4674:   ip_msg_len = ip_hlen + pim_msg_size;
 4675:   result = pim_pim_packet(ifp, buf, ip_msg_len);
 4676:   if (result) {
 4677:     vty_out(vty, "pim_pim_packet(len=%d) returned failure: %d%s",
 4678: 	    ip_msg_len, result, VTY_NEWLINE);
 4679:     return CMD_WARNING;
 4680:   }
 4681: 
 4682:   return CMD_SUCCESS;
 4683: }
 4684: 
 4685: DEFUN (test_pim_receive_join,
 4686:        test_pim_receive_join_cmd,
 4687:        "test pim receive join INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
 4688:        "Test\n"
 4689:        "Test PIM protocol\n"
 4690:        "Test PIM message reception\n"
 4691:        "Test PIM join reception from neighbor\n"
 4692:        "Interface\n"
 4693:        "Neighbor holdtime\n"
 4694:        "Upstream neighbor unicast destination address\n"
 4695:        "Downstream neighbor unicast source address\n"
 4696:        "Multicast group address\n"
 4697:        "Unicast source address\n")
 4698: {
 4699:   return recv_joinprune(vty, argv, 1 /* src_is_join=true */);
 4700: }
 4701: 
 4702: DEFUN (test_pim_receive_prune,
 4703:        test_pim_receive_prune_cmd,
 4704:        "test pim receive prune INTERFACE <0-65535> A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
 4705:        "Test\n"
 4706:        "Test PIM protocol\n"
 4707:        "Test PIM message reception\n"
 4708:        "Test PIM prune reception from neighbor\n"
 4709:        "Interface\n"
 4710:        "Neighbor holdtime\n"
 4711:        "Upstream neighbor unicast destination address\n"
 4712:        "Downstream neighbor unicast source address\n"
 4713:        "Multicast group address\n"
 4714:        "Unicast source address\n")
 4715: {
 4716:   return recv_joinprune(vty, argv, 0 /* src_is_join=false */);
 4717: }
 4718: 
 4719: DEFUN (test_pim_receive_upcall,
 4720:        test_pim_receive_upcall_cmd,
 4721:        "test pim receive upcall (nocache|wrongvif|wholepkt) <0-65535> A.B.C.D A.B.C.D",
 4722:        "Test\n"
 4723:        "Test PIM protocol\n"
 4724:        "Test PIM message reception\n"
 4725:        "Test reception of kernel upcall\n"
 4726:        "NOCACHE kernel upcall\n"
 4727:        "WRONGVIF kernel upcall\n"
 4728:        "WHOLEPKT kernel upcall\n"
 4729:        "Input interface vif index\n"
 4730:        "Multicast group address\n"
 4731:        "Multicast source address\n")
 4732: {
 4733:   struct igmpmsg msg;
 4734:   const char *upcall_type;
 4735:   const char *group_str;
 4736:   const char *source_str;
 4737:   int result;
 4738: 
 4739:   upcall_type = argv[0];
 4740: 
 4741:   if (upcall_type[0] == 'n')
 4742:     msg.im_msgtype = IGMPMSG_NOCACHE;
 4743:   else if (upcall_type[1] == 'r')
 4744:     msg.im_msgtype = IGMPMSG_WRONGVIF;
 4745:   else if (upcall_type[1] == 'h')
 4746:     msg.im_msgtype = IGMPMSG_WHOLEPKT;
 4747:   else {
 4748:     vty_out(vty, "Unknown kernel upcall type: %s%s",
 4749: 	    upcall_type, VTY_NEWLINE);
 4750:     return CMD_WARNING;
 4751:   }
 4752: 
 4753:   msg.im_vif = atoi(argv[1]);
 4754: 
 4755:   /* Group address */
 4756:   group_str = argv[2];
 4757:   result = inet_pton(AF_INET, group_str, &msg.im_dst);
 4758:   if (result <= 0) {
 4759:     vty_out(vty, "Bad group address %s: errno=%d: %s%s",
 4760: 	    group_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4761:     return CMD_WARNING;
 4762:   }
 4763: 
 4764:   /* Source address */
 4765:   source_str = argv[3];
 4766:   result = inet_pton(AF_INET, source_str, &msg.im_src);
 4767:   if (result <= 0) {
 4768:     vty_out(vty, "Bad source address %s: errno=%d: %s%s",
 4769: 	    source_str, errno, safe_strerror(errno), VTY_NEWLINE);
 4770:     return CMD_WARNING;
 4771:   }
 4772: 
 4773:   msg.im_mbz = 0; /* Must be zero */
 4774: 
 4775:   result = pim_mroute_msg(-1, (char *) &msg, sizeof(msg));
 4776:   if (result) {
 4777:     vty_out(vty, "pim_mroute_msg(len=%zu) returned failure: %d%s",
 4778: 	    sizeof(msg), result, VTY_NEWLINE);
 4779:     return CMD_WARNING;
 4780:   }
 4781: 
 4782:   return CMD_SUCCESS;
 4783: }
 4784: 
 4785: void pim_cmd_init()
 4786: {
 4787:   install_node (&pim_global_node, pim_global_config_write);       /* PIM_NODE */
 4788:   install_node (&interface_node, pim_interface_config_write); /* INTERFACE_NODE */
 4789: 
 4790:   install_element (CONFIG_NODE, &ip_multicast_routing_cmd);
 4791:   install_element (CONFIG_NODE, &no_ip_multicast_routing_cmd);
 4792:   install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
 4793:   install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd); 
 4794: #if 0
 4795:   install_element (CONFIG_NODE, &interface_cmd); /* from if.h */
 4796: #else
 4797:   install_element (CONFIG_NODE, &pim_interface_cmd);
 4798: #endif
 4799:   install_element (CONFIG_NODE, &no_interface_cmd); /* from if.h */
 4800: 
 4801:   install_default (INTERFACE_NODE);
 4802:   install_element (INTERFACE_NODE, &interface_ip_igmp_cmd);
 4803:   install_element (INTERFACE_NODE, &interface_no_ip_igmp_cmd); 
 4804:   install_element (INTERFACE_NODE, &interface_ip_igmp_join_cmd);
 4805:   install_element (INTERFACE_NODE, &interface_no_ip_igmp_join_cmd); 
 4806:   install_element (INTERFACE_NODE, &interface_ip_igmp_query_interval_cmd);
 4807:   install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_interval_cmd); 
 4808:   install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_cmd);
 4809:   install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_cmd); 
 4810:   install_element (INTERFACE_NODE, &interface_ip_igmp_query_max_response_time_dsec_cmd);
 4811:   install_element (INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd); 
 4812:   install_element (INTERFACE_NODE, &interface_ip_pim_ssm_cmd);
 4813:   install_element (INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd);
 4814:   install_element (INTERFACE_NODE, &interface_ip_pim_drprio_cmd);
 4815:   install_element (INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
 4816:   install_element (INTERFACE_NODE, &interface_ip_pim_hello_cmd);
 4817:   install_element (INTERFACE_NODE, &interface_ip_pim_hello_hold_cmd);
 4818:   install_element (INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
 4819: 
 4820:   // Static mroutes NEB
 4821:   install_element (INTERFACE_NODE, &interface_ip_mroute_cmd);
 4822:   install_element (INTERFACE_NODE, &interface_ip_mroute_source_cmd);
 4823:   install_element (INTERFACE_NODE, &interface_no_ip_mroute_cmd);
 4824:   install_element (INTERFACE_NODE, &interface_no_ip_mroute_source_cmd);
 4825: 
 4826:   install_element (VIEW_NODE, &show_ip_igmp_interface_cmd);
 4827:   install_element (VIEW_NODE, &show_ip_igmp_join_cmd);
 4828:   install_element (VIEW_NODE, &show_ip_igmp_parameters_cmd);
 4829:   install_element (VIEW_NODE, &show_ip_igmp_groups_cmd);
 4830:   install_element (VIEW_NODE, &show_ip_igmp_groups_retransmissions_cmd);
 4831:   install_element (VIEW_NODE, &show_ip_igmp_sources_cmd);
 4832:   install_element (VIEW_NODE, &show_ip_igmp_sources_retransmissions_cmd);
 4833:   install_element (VIEW_NODE, &show_ip_igmp_querier_cmd);
 4834:   install_element (VIEW_NODE, &show_ip_pim_assert_cmd);
 4835:   install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
 4836:   install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
 4837:   install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
 4838:   install_element (VIEW_NODE, &show_ip_pim_dr_cmd);
 4839:   install_element (VIEW_NODE, &show_ip_pim_hello_cmd);
 4840:   install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
 4841:   install_element (VIEW_NODE, &show_ip_pim_join_cmd);
 4842:   install_element (VIEW_NODE, &show_ip_pim_jp_override_interval_cmd);
 4843:   install_element (VIEW_NODE, &show_ip_pim_lan_prune_delay_cmd);
 4844:   install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
 4845:   install_element (VIEW_NODE, &show_ip_pim_neighbor_cmd);
 4846:   install_element (VIEW_NODE, &show_ip_pim_rpf_cmd);
 4847:   install_element (VIEW_NODE, &show_ip_pim_secondary_cmd);
 4848:   install_element (VIEW_NODE, &show_ip_pim_upstream_cmd);
 4849:   install_element (VIEW_NODE, &show_ip_pim_upstream_join_desired_cmd);
 4850:   install_element (VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
 4851:   install_element (VIEW_NODE, &show_ip_multicast_cmd);
 4852:   install_element (VIEW_NODE, &show_ip_mroute_cmd);
 4853:   install_element (VIEW_NODE, &show_ip_mroute_count_cmd);
 4854:   install_element (VIEW_NODE, &show_ip_rib_cmd);
 4855:   install_element (VIEW_NODE, &show_ip_ssmpingd_cmd);
 4856:   install_element (VIEW_NODE, &show_debugging_pim_cmd);
 4857: 
 4858:   install_element (ENABLE_NODE, &clear_ip_interfaces_cmd);
 4859:   install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
 4860:   install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
 4861:   install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
 4862:   install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
 4863: 
 4864:   install_element (ENABLE_NODE, &show_ip_igmp_interface_cmd);
 4865:   install_element (ENABLE_NODE, &show_ip_igmp_join_cmd);
 4866:   install_element (ENABLE_NODE, &show_ip_igmp_parameters_cmd);
 4867:   install_element (ENABLE_NODE, &show_ip_igmp_groups_cmd);
 4868:   install_element (ENABLE_NODE, &show_ip_igmp_groups_retransmissions_cmd);
 4869:   install_element (ENABLE_NODE, &show_ip_igmp_sources_cmd);
 4870:   install_element (ENABLE_NODE, &show_ip_igmp_sources_retransmissions_cmd);
 4871:   install_element (ENABLE_NODE, &show_ip_igmp_querier_cmd);
 4872:   install_element (ENABLE_NODE, &show_ip_pim_address_cmd);
 4873:   install_element (ENABLE_NODE, &show_ip_pim_assert_cmd);
 4874:   install_element (ENABLE_NODE, &show_ip_pim_assert_internal_cmd);
 4875:   install_element (ENABLE_NODE, &show_ip_pim_assert_metric_cmd);
 4876:   install_element (ENABLE_NODE, &show_ip_pim_assert_winner_metric_cmd);
 4877:   install_element (ENABLE_NODE, &show_ip_pim_dr_cmd);
 4878:   install_element (ENABLE_NODE, &show_ip_pim_hello_cmd);
 4879:   install_element (ENABLE_NODE, &show_ip_pim_interface_cmd);
 4880:   install_element (ENABLE_NODE, &show_ip_pim_join_cmd);
 4881:   install_element (ENABLE_NODE, &show_ip_pim_jp_override_interval_cmd);
 4882:   install_element (ENABLE_NODE, &show_ip_pim_lan_prune_delay_cmd);
 4883:   install_element (ENABLE_NODE, &show_ip_pim_local_membership_cmd);
 4884:   install_element (ENABLE_NODE, &show_ip_pim_neighbor_cmd);
 4885:   install_element (ENABLE_NODE, &show_ip_pim_rpf_cmd);
 4886:   install_element (ENABLE_NODE, &show_ip_pim_secondary_cmd);
 4887:   install_element (ENABLE_NODE, &show_ip_pim_upstream_cmd);
 4888:   install_element (ENABLE_NODE, &show_ip_pim_upstream_join_desired_cmd);
 4889:   install_element (ENABLE_NODE, &show_ip_pim_upstream_rpf_cmd);
 4890:   install_element (ENABLE_NODE, &show_ip_multicast_cmd);
 4891:   install_element (ENABLE_NODE, &show_ip_mroute_cmd);
 4892:   install_element (ENABLE_NODE, &show_ip_mroute_count_cmd);
 4893:   install_element (ENABLE_NODE, &show_ip_rib_cmd);
 4894:   install_element (ENABLE_NODE, &show_ip_ssmpingd_cmd);
 4895:   install_element (ENABLE_NODE, &show_debugging_pim_cmd);
 4896: 
 4897:   install_element (ENABLE_NODE, &test_igmp_receive_report_cmd);
 4898:   install_element (ENABLE_NODE, &test_pim_receive_assert_cmd);
 4899:   install_element (ENABLE_NODE, &test_pim_receive_dump_cmd);
 4900:   install_element (ENABLE_NODE, &test_pim_receive_hello_cmd);
 4901:   install_element (ENABLE_NODE, &test_pim_receive_join_cmd);
 4902:   install_element (ENABLE_NODE, &test_pim_receive_prune_cmd);
 4903:   install_element (ENABLE_NODE, &test_pim_receive_upcall_cmd);
 4904: 
 4905:   install_element (ENABLE_NODE, &debug_igmp_cmd);
 4906:   install_element (ENABLE_NODE, &no_debug_igmp_cmd);
 4907:   install_element (ENABLE_NODE, &undebug_igmp_cmd);
 4908:   install_element (ENABLE_NODE, &debug_igmp_events_cmd);
 4909:   install_element (ENABLE_NODE, &no_debug_igmp_events_cmd);
 4910:   install_element (ENABLE_NODE, &undebug_igmp_events_cmd);
 4911:   install_element (ENABLE_NODE, &debug_igmp_packets_cmd);
 4912:   install_element (ENABLE_NODE, &no_debug_igmp_packets_cmd);
 4913:   install_element (ENABLE_NODE, &undebug_igmp_packets_cmd);
 4914:   install_element (ENABLE_NODE, &debug_igmp_trace_cmd);
 4915:   install_element (ENABLE_NODE, &no_debug_igmp_trace_cmd);
 4916:   install_element (ENABLE_NODE, &undebug_igmp_trace_cmd);
 4917:   install_element (ENABLE_NODE, &debug_mroute_cmd);
 4918:   install_element (ENABLE_NODE, &no_debug_mroute_cmd);
 4919:   install_element (ENABLE_NODE, &debug_static_cmd);
 4920:   install_element (ENABLE_NODE, &no_debug_static_cmd);
 4921:   install_element (ENABLE_NODE, &debug_pim_cmd);
 4922:   install_element (ENABLE_NODE, &no_debug_pim_cmd);
 4923:   install_element (ENABLE_NODE, &undebug_pim_cmd);
 4924:   install_element (ENABLE_NODE, &debug_pim_events_cmd);
 4925:   install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
 4926:   install_element (ENABLE_NODE, &undebug_pim_events_cmd);
 4927:   install_element (ENABLE_NODE, &debug_pim_packets_cmd);
 4928:   install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
 4929:   install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
 4930:   install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
 4931:   install_element (ENABLE_NODE, &undebug_pim_packets_cmd);
 4932:   install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
 4933:   install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
 4934:   install_element (ENABLE_NODE, &undebug_pim_packetdump_send_cmd);
 4935:   install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
 4936:   install_element (ENABLE_NODE, &no_debug_pim_packetdump_recv_cmd);
 4937:   install_element (ENABLE_NODE, &undebug_pim_packetdump_recv_cmd);
 4938:   install_element (ENABLE_NODE, &debug_pim_trace_cmd);
 4939:   install_element (ENABLE_NODE, &no_debug_pim_trace_cmd);
 4940:   install_element (ENABLE_NODE, &undebug_pim_trace_cmd);
 4941:   install_element (ENABLE_NODE, &debug_ssmpingd_cmd);
 4942:   install_element (ENABLE_NODE, &no_debug_ssmpingd_cmd);
 4943:   install_element (ENABLE_NODE, &undebug_ssmpingd_cmd);
 4944:   install_element (ENABLE_NODE, &debug_pim_zebra_cmd);
 4945:   install_element (ENABLE_NODE, &no_debug_pim_zebra_cmd);
 4946:   install_element (ENABLE_NODE, &undebug_pim_zebra_cmd);
 4947: 
 4948:   install_element (CONFIG_NODE, &debug_igmp_cmd);
 4949:   install_element (CONFIG_NODE, &no_debug_igmp_cmd);
 4950:   install_element (CONFIG_NODE, &undebug_igmp_cmd);
 4951:   install_element (CONFIG_NODE, &debug_igmp_events_cmd);
 4952:   install_element (CONFIG_NODE, &no_debug_igmp_events_cmd);
 4953:   install_element (CONFIG_NODE, &undebug_igmp_events_cmd);
 4954:   install_element (CONFIG_NODE, &debug_igmp_packets_cmd);
 4955:   install_element (CONFIG_NODE, &no_debug_igmp_packets_cmd);
 4956:   install_element (CONFIG_NODE, &undebug_igmp_packets_cmd);
 4957:   install_element (CONFIG_NODE, &debug_igmp_trace_cmd);
 4958:   install_element (CONFIG_NODE, &no_debug_igmp_trace_cmd);
 4959:   install_element (CONFIG_NODE, &undebug_igmp_trace_cmd);
 4960:   install_element (CONFIG_NODE, &debug_mroute_cmd);
 4961:   install_element (CONFIG_NODE, &no_debug_mroute_cmd);
 4962:   install_element (CONFIG_NODE, &debug_static_cmd);
 4963:   install_element (CONFIG_NODE, &no_debug_static_cmd);
 4964:   install_element (CONFIG_NODE, &debug_pim_cmd);
 4965:   install_element (CONFIG_NODE, &no_debug_pim_cmd);
 4966:   install_element (CONFIG_NODE, &undebug_pim_cmd);
 4967:   install_element (CONFIG_NODE, &debug_pim_events_cmd);
 4968:   install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
 4969:   install_element (CONFIG_NODE, &undebug_pim_events_cmd);
 4970:   install_element (CONFIG_NODE, &debug_pim_packets_cmd);
 4971:   install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
 4972:   install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
 4973:   install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
 4974:   install_element (CONFIG_NODE, &undebug_pim_packets_cmd);
 4975:   install_element (CONFIG_NODE, &debug_pim_trace_cmd);
 4976:   install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
 4977:   install_element (CONFIG_NODE, &undebug_pim_trace_cmd);
 4978:   install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
 4979:   install_element (CONFIG_NODE, &no_debug_ssmpingd_cmd);
 4980:   install_element (CONFIG_NODE, &undebug_ssmpingd_cmd);
 4981:   install_element (CONFIG_NODE, &debug_pim_zebra_cmd);
 4982:   install_element (CONFIG_NODE, &no_debug_pim_zebra_cmd);
 4983:   install_element (CONFIG_NODE, &undebug_pim_zebra_cmd);
 4984: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>