]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_cmd.c
Merge branch 'master' into pim_5549
[mirror_frr.git] / pimd / pim_cmd.c
index 093497d44e8943e3a3eabb9f5dacc5fd603d1f57..627971d3f9779e7fc8fb70687683010e96f2ce87 100644 (file)
@@ -16,7 +16,6 @@
   along with this program; see the file COPYING; if not, write to the
   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
   MA 02110-1301 USA
-  
 */
 
 #include <zebra.h>
@@ -55,6 +54,7 @@
 #include "pim_rp.h"
 #include "pim_zlookup.h"
 #include "pim_msdp.h"
+#include "pim_ssm.h"
 
 static struct cmd_node pim_global_node = {
   PIM_NODE,
@@ -817,6 +817,7 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname, u_ch
     mloop = pim_socket_mcastloop_get(pim_ifp->pim_sock_fd);
 
     if (uj) {
+      char pbuf[PREFIX2STR_BUFFER];
       json_row = json_object_new_object();
       json_object_pim_ifp_add(json_row, ifp);
 
@@ -828,7 +829,8 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname, u_ch
 
         sec_list = json_object_new_array();
         for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, sec_node, sec_addr)) {
-          json_object_array_add(sec_list, json_object_new_string(inet_ntoa(sec_addr->addr)));
+          json_object_array_add(sec_list,
+                                json_object_new_string(prefix2str(&sec_addr->addr, pbuf, PREFIX2STR_BUFFER)));
         }
         json_object_object_add(json_row, "secondaryAddressList", sec_list);
       }
@@ -919,11 +921,12 @@ static void pim_show_interfaces_single(struct vty *vty, const char *ifname, u_ch
         vty_out(vty, "Use Source : %s%s", inet_ntoa(pim_ifp->update_source), VTY_NEWLINE);
       }
       if (pim_ifp->sec_addr_list) {
+        char pbuf[PREFIX2STR_BUFFER];
         vty_out(vty, "Address    : %s (primary)%s",
-                                    inet_ntoa(ifaddr), VTY_NEWLINE);
+                inet_ntoa(ifaddr), VTY_NEWLINE);
         for (ALL_LIST_ELEMENTS_RO(pim_ifp->sec_addr_list, sec_node, sec_addr)) {
           vty_out(vty, "             %s%s",
-                                    inet_ntoa(sec_addr->addr), VTY_NEWLINE);
+                  prefix2str(&sec_addr->addr, pbuf, PREFIX2STR_BUFFER), VTY_NEWLINE);
         }
       } else {
         vty_out(vty, "Address    : %s%s", inet_ntoa(ifaddr), VTY_NEWLINE);
@@ -1169,7 +1172,8 @@ static void pim_show_join(struct vty *vty, u_char uj)
       json_object_string_add(json_row, "upTime", uptime);
       json_object_string_add(json_row, "expire", expire);
       json_object_string_add(json_row, "prune", prune);
-      json_object_string_add(json_row, "channelJoinName", pim_ifchannel_ifjoin_name(ch->ifjoin_state));
+      json_object_string_add(json_row, "channelJoinName",
+                             pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags));
       if (PIM_IF_FLAG_TEST_S_G_RPT(ch->flags))
         json_object_int_add(json_row, "SGRpt", 1);
 
@@ -1188,7 +1192,7 @@ static void pim_show_join(struct vty *vty, u_char uj)
              inet_ntoa(ifaddr),
              ch_src_str,
              ch_grp_str,
-             pim_ifchannel_ifjoin_name(ch->ifjoin_state),
+             pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
              uptime,
              expire,
              prune,
@@ -1368,21 +1372,19 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
   if (uj) {
     json = json_object_new_object();
   } else {
-    vty_out(vty, "%sSource           Group            IIF    OIL%s", VTY_NEWLINE, VTY_NEWLINE);
+    vty_out(vty, "Codes: J -> Pim Join, I -> IGMP Report, S -> Source, * -> Inherited from (*,G)");
+    vty_out(vty, "%sInstalled Source           Group            IIF      OIL%s", VTY_NEWLINE, VTY_NEWLINE);
   }
 
   for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
     char grp_str[INET_ADDRSTRLEN];
     char src_str[INET_ADDRSTRLEN];
-    char in_ifname[16];
-    char out_ifname[16];
+    char in_ifname[INTERFACE_NAMSIZ+1];
+    char out_ifname[INTERFACE_NAMSIZ+1];
     int oif_vif_index;
     struct interface *ifp_in;
     first_oif = 1;
 
-    if (!c_oil->installed)
-      continue;
-
     pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
     pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, src_str, sizeof(src_str));
     ifp_in = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
@@ -1425,9 +1427,18 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
       if (!json_ifp_in) {
         json_ifp_in = json_object_new_object();
         json_object_object_add(json_source, in_ifname, json_ifp_in);
+        json_object_int_add (json_source, "Installed", c_oil->installed);
+        json_object_int_add (json_source, "RefCount", c_oil->oil_ref_count);
+        json_object_int_add (json_source, "OilListSize", c_oil->oil_size);
+        json_object_int_add (json_source, "OilRescan", c_oil->oil_inherited_rescan);
+        json_object_int_add (json_source, "LastUsed", c_oil->cc.lastused);
+        json_object_int_add (json_source, "PacketCount", c_oil->cc.pktcnt);
+        json_object_int_add (json_source, "ByteCount", c_oil->cc.bytecnt);
+        json_object_int_add (json_source, "WrongInterface", c_oil->cc.wrong_if);
       }
     } else {
-        vty_out(vty, "%-15s  %-15s  %-5s  ",
+        vty_out(vty, "%-9d %-15s  %-15s  %-7s  ",
+                c_oil->installed,
                 src_str,
                 grp_str,
                 ifp_in->name);
@@ -1456,16 +1467,25 @@ pim_show_state(struct vty *vty, const char *src_or_group, const char *group, u_c
         json_object_string_add(json_ifp_out, "group", grp_str);
         json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
         json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
+        json_object_int_add(json_ifp_out, "installed", c_oil->installed);
 
         json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
       } else {
         if (first_oif)
           {
             first_oif = 0;
-            vty_out(vty, "%s", out_ifname);
+            vty_out(vty, "%s(%c%c%c%c)", out_ifname,
+                    (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
+                    (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
+                    (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
+                    (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ');
           }
         else
-          vty_out(vty, ",%s", out_ifname);
+          vty_out(vty, ", %s(%c%c%c%c)", out_ifname,
+                  (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_IGMP) ? 'I' : ' ',
+                  (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) ? 'J' : ' ',
+                  (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE) ? 'S' : ' ',
+                  (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) ? '*' : ' ' );
       }
     }
 
@@ -1591,13 +1611,9 @@ static void pim_show_neighbors_secondary(struct vty *vty)
                     neigh_src_str, sizeof(neigh_src_str));
 
       for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list, prefix_node, p)) {
-       char neigh_sec_str[INET_ADDRSTRLEN];
-
-       if (p->family != AF_INET)
-         continue;
+       char neigh_sec_str[100];
 
-       pim_inet4_dump("<src?>", p->u.prefix4,
-                      neigh_sec_str, sizeof(neigh_sec_str));
+       prefix2str(p, neigh_sec_str, 100);
 
        vty_out(vty, "%-9s %-15s %-15s %-15s%s",
                ifp->name,
@@ -1636,6 +1652,44 @@ json_object_pim_upstream_add (json_object *json, struct pim_upstream *up)
     json_object_boolean_true_add(json, "sourceMsdp");
 }
 
+static const char *
+pim_upstream_state2brief_str (enum pim_upstream_state join_state, char *state_str)
+{
+  switch (join_state)
+    {
+    case PIM_UPSTREAM_NOTJOINED:
+      strcpy (state_str, "NotJ");
+      break;
+    case PIM_UPSTREAM_JOINED:
+      strcpy (state_str, "J");
+      break;
+    default:
+      strcpy (state_str, "Unk");
+    }
+  return state_str;
+}
+
+static const char *
+pim_reg_state2brief_str (enum pim_reg_state reg_state, char *state_str)
+{
+  switch (reg_state)
+    {
+    case PIM_REG_NOINFO:
+      strcpy (state_str, "RegNI");
+      break;
+    case PIM_REG_JOIN:
+      strcpy (state_str, "RegJ");
+      break;
+    case PIM_REG_JOIN_PENDING:
+    case PIM_REG_PRUNE:
+      strcpy (state_str, "RegP");
+      break;
+    default:
+      strcpy (state_str, "Unk");
+    }
+  return state_str;
+}
+
 static void pim_show_upstream(struct vty *vty, u_char uj)
 {
   struct listnode     *upnode;
@@ -1660,15 +1714,38 @@ static void pim_show_upstream(struct vty *vty, u_char uj)
     char rs_timer[10];
     char ka_timer[10];
     char msdp_reg_timer[10];
+    char state_str[PIM_REG_STATE_STR_LEN];
 
     pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
     pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
     pim_time_uptime(uptime, sizeof(uptime), now - up->state_transition);
     pim_time_timer_to_hhmmss (join_timer, sizeof(join_timer), up->t_join_timer);
+
+    /*
+     * If we have a J/P timer for the neighbor display that
+     */
+    if (!up->t_join_timer)
+      {
+        struct pim_neighbor *nbr;
+
+        nbr = pim_neighbor_find (up->rpf.source_nexthop.interface,
+                                 up->rpf.rpf_addr.u.prefix4);
+        if (nbr)
+          pim_time_timer_to_hhmmss (join_timer, sizeof(join_timer), nbr->jp_timer);
+      }
+
     pim_time_timer_to_hhmmss (rs_timer, sizeof (rs_timer), up->t_rs_timer);
     pim_time_timer_to_hhmmss (ka_timer, sizeof (ka_timer), up->t_ka_timer);
     pim_time_timer_to_hhmmss (msdp_reg_timer, sizeof (msdp_reg_timer), up->t_msdp_reg_timer);
 
+    pim_upstream_state2brief_str (up->join_state, state_str);
+    if (up->reg_state != PIM_REG_NOINFO) {
+      char tmp_str[PIM_REG_STATE_STR_LEN];
+
+      sprintf (state_str + strlen (state_str), ",%s",
+               pim_reg_state2brief_str (up->reg_state, tmp_str));
+    }
+
     if (uj) {
       json_object_object_get_ex(json, grp_str, &json_group);
 
@@ -1682,7 +1759,9 @@ static void pim_show_upstream(struct vty *vty, u_char uj)
       json_object_string_add(json_row, "inboundInterface", up->rpf.source_nexthop.interface->name);
       json_object_string_add(json_row, "source", src_str);
       json_object_string_add(json_row, "group", grp_str);
-      json_object_string_add(json_row, "state", pim_upstream_state2str (up->join_state));
+      json_object_string_add(json_row, "state", state_str);
+      json_object_string_add(json_row, "joinState", pim_upstream_state2str (up->join_state));
+      json_object_string_add(json_row, "regState", pim_reg_state2str (up->reg_state, state_str));
       json_object_string_add(json_row, "upTime", uptime);
       json_object_string_add(json_row, "joinTimer", join_timer);
       json_object_string_add(json_row, "resetTimer", rs_timer);
@@ -1696,7 +1775,7 @@ static void pim_show_upstream(struct vty *vty, u_char uj)
               up->rpf.source_nexthop.interface->name,
               src_str,
               grp_str,
-              pim_upstream_state2str (up->join_state),
+              state_str,
               uptime,
               join_timer,
               rs_timer,
@@ -2335,44 +2414,6 @@ static void mroute_del_all()
   }
 }
 
-static void static_mroute_add_all()
-{
-  struct listnode     *node;
-  struct static_route *s_route;
-
-  for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
-    if (pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__)) {
-      /* just log warning */
-      char source_str[INET_ADDRSTRLEN];
-      char group_str[INET_ADDRSTRLEN];
-      pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
-      pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-      zlog_warn("%s %s: (S,G)=(%s,%s) failure writing MFC",
-      __FILE__, __PRETTY_FUNCTION__,
-      source_str, group_str);
-    }
-  }
-}
-
-static void static_mroute_del_all()
-{
-   struct listnode     *node;
-   struct static_route *s_route;
-
-   for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
-     if (pim_mroute_del(&s_route->c_oil, __PRETTY_FUNCTION__)) {
-       /* just log warning */
-       char source_str[INET_ADDRSTRLEN];
-       char group_str[INET_ADDRSTRLEN];
-       pim_inet4_dump("<source?>", s_route->c_oil.oil.mfcc_origin, source_str, sizeof(source_str));
-       pim_inet4_dump("<group?>", s_route->c_oil.oil.mfcc_mcastgrp, group_str, sizeof(group_str));
-       zlog_warn("%s %s: (S,G)=(%s,%s) failure clearing MFC",
-       __FILE__, __PRETTY_FUNCTION__,
-       source_str, group_str);
-     }
-   }
-}
-
 DEFUN (clear_ip_mroute,
        clear_ip_mroute_cmd,
        "clear ip mroute",
@@ -2424,8 +2465,11 @@ DEFUN (show_ip_igmp_interface,
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (argv[4]->arg)
-    igmp_show_interfaces_single(vty, argv[4]->arg, uj);
+  int idx = 0;
+
+  if (argv_find(argv, argc, "detail", &idx) ||
+      argv_find(argv, argc, "WORD", &idx))
+    igmp_show_interfaces_single(vty, argv[idx]->arg, uj);
   else
     igmp_show_interfaces(vty, uj);
 
@@ -2553,34 +2597,6 @@ DEFUN (show_ip_pim_assert_winner_metric,
   return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_pim_dr,
-       show_ip_pim_dr_cmd,
-       "show ip pim designated-router [json]",
-       SHOW_STR
-       IP_STR
-       PIM_STR
-       "PIM interface designated router\n")
-{
-  u_char uj = use_json(argc, argv);
-  pim_show_dr(vty, uj);
-
-  return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_pim_hello,
-       show_ip_pim_hello_cmd,
-       "show ip pim hello [json]",
-       SHOW_STR
-       IP_STR
-       PIM_STR
-       "PIM interface hello information\n")
-{
-  u_char uj = use_json(argc, argv);
-  pim_show_hello(vty, uj);
-
-  return CMD_SUCCESS;
-}
-
 DEFUN (show_ip_pim_interface,
        show_ip_pim_interface_cmd,
        "show ip pim interface [detail|WORD] [json]",
@@ -2593,8 +2609,12 @@ DEFUN (show_ip_pim_interface,
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (argv[4]->arg)
-    pim_show_interfaces_single(vty, argv[4]->arg, uj);
+  int idx = 0;
+
+  if (argv_find(argv, argc, "WORD", &idx) ||
+      argv_find(argv, argc, "detail", &idx))
+    pim_show_interfaces_single(vty, argv[idx]->arg, uj);
+
   else
     pim_show_interfaces(vty, uj);
 
@@ -2607,7 +2627,8 @@ DEFUN (show_ip_pim_join,
        SHOW_STR
        IP_STR
        PIM_STR
-       "PIM interface join information\n")
+       "PIM interface join information\n"
+       JSON_STR)
 {
   u_char uj = use_json(argc, argv);
   pim_show_join(vty, uj);
@@ -2621,7 +2642,8 @@ DEFUN (show_ip_pim_local_membership,
        SHOW_STR
        IP_STR
        PIM_STR
-       "PIM interface local-membership\n")
+       "PIM interface local-membership\n"
+       JSON_STR)
 {
   u_char uj = use_json(argc, argv);
   pim_show_membership(vty, uj);
@@ -2641,8 +2663,11 @@ DEFUN (show_ip_pim_neighbor,
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (argv[4]->arg)
-    pim_show_neighbors_single(vty, argv[4]->arg, uj);
+  int idx = 0;
+
+  if (argv_find(argv, argc, "detail", &idx) ||
+      argv_find(argv, argc, "WORD", &idx))
+    pim_show_neighbors_single(vty, argv[idx]->arg, uj);
   else
     pim_show_neighbors(vty, uj);
 
@@ -2664,7 +2689,7 @@ DEFUN (show_ip_pim_secondary,
 
 DEFUN (show_ip_pim_state,
        show_ip_pim_state_cmd,
-       "show ip pim state [A.B.C.D] [A.B.C.D] [json]",
+       "show ip pim state [A.B.C.D [A.B.C.D]] [json]",
        SHOW_STR
        IP_STR
        PIM_STR
@@ -2676,9 +2701,16 @@ DEFUN (show_ip_pim_state,
   const char *src_or_group = NULL;
   const char *group = NULL;
   u_char uj = use_json(argc, argv);
+  if (uj)
+    argc--;
 
-  src_or_group = argv[4]->arg;
-  group = argv[5]->arg;
+  if (argc == 6)
+    {
+      src_or_group = argv[4]->arg;
+      group = argv[5]->arg;
+    }
+  else if (argc == 5)
+    src_or_group = argv[4]->arg;
 
   pim_show_state(vty, src_or_group, group, uj);
 
@@ -2817,39 +2849,23 @@ DEFUN (show_ip_multicast,
 {
   time_t now = pim_time_monotonic_sec();
 
-  if (PIM_MROUTE_IS_ENABLED) {
-    char uptime[10];
+  char uptime[10];
 
-    vty_out(vty, "Mroute socket descriptor: %d%s",
-           qpim_mroute_socket_fd,
-           VTY_NEWLINE);
+  vty_out(vty, "Mroute socket descriptor: %d%s",
+          qpim_mroute_socket_fd,
+          VTY_NEWLINE);
 
-    pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
-    vty_out(vty, "Mroute socket uptime: %s%s",
-           uptime,
-           VTY_NEWLINE);
-  }
-  else {
-    vty_out(vty, "Multicast disabled%s",
-           VTY_NEWLINE);
-  }
+  pim_time_uptime(uptime, sizeof(uptime), now - qpim_mroute_socket_creation);
+  vty_out(vty, "Mroute socket uptime: %s%s",
+          uptime,
+          VTY_NEWLINE);
 
   vty_out(vty, "%s", VTY_NEWLINE);
-  vty_out(vty, "Zclient update socket: ");
-  if (qpim_zclient_update) {
-    vty_out(vty, "%d failures=%d%s", qpim_zclient_update->sock,
-           qpim_zclient_update->fail, VTY_NEWLINE);
-  }
-  else {
-    vty_out(vty, "<null zclient>%s", VTY_NEWLINE);
-  }
 
+  pim_zebra_zclient_update (vty);
   pim_zlookup_show_ip_multicast (vty);
 
   vty_out(vty, "%s", VTY_NEWLINE);
-  vty_out(vty, "Current highest VifIndex: %d%s",
-         qpim_mroute_oif_highest_vif_index,
-         VTY_NEWLINE);
   vty_out(vty, "Maximum highest VifIndex: %d%s",
          PIM_MAX_USABLE_VIFS,
          VTY_NEWLINE);
@@ -2884,10 +2900,17 @@ static void show_mroute(struct vty *vty, u_char uj)
   json_object *json = NULL;
   json_object *json_group = NULL;
   json_object *json_source = NULL;
-  json_object *json_ifp_in = NULL;
+  json_object *json_oil = NULL;
   json_object *json_ifp_out = NULL;
   int found_oif = 0;
   int first = 1;
+  char grp_str[INET_ADDRSTRLEN];
+  char src_str[INET_ADDRSTRLEN];
+  char in_ifname[INTERFACE_NAMSIZ+1];
+  char out_ifname[INTERFACE_NAMSIZ+1];
+  int oif_vif_index;
+  struct interface *ifp_in;
+  char proto[100];
 
   if (uj) {
     json = json_object_new_object();
@@ -2900,16 +2923,9 @@ static void show_mroute(struct vty *vty, u_char uj)
 
   /* print list of PIM and IGMP routes */
   for (ALL_LIST_ELEMENTS_RO(pim_channel_oil_list, node, c_oil)) {
-    char grp_str[INET_ADDRSTRLEN];
-    char src_str[INET_ADDRSTRLEN];
-    char in_ifname[16];
-    char out_ifname[16];
-    int oif_vif_index;
-    char proto[100];
-    struct interface *ifp_in;
     found_oif = 0;
     first = 1;
-    if (!c_oil->installed)
+    if (!c_oil->installed && !uj)
       continue;
 
     pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, grp_str, sizeof(grp_str));
@@ -2940,12 +2956,12 @@ static void show_mroute(struct vty *vty, u_char uj)
       }
 
       /* Find the inbound interface nested under the source, create it if it doesn't exist */
-      json_object_object_get_ex(json_source, in_ifname, &json_ifp_in);
-
-      if (!json_ifp_in) {
-        json_ifp_in = json_object_new_object();
-        json_object_object_add(json_source, in_ifname, json_ifp_in);
-      }
+      json_object_int_add(json_source, "installed", c_oil->installed);
+      json_object_int_add(json_source, "refCount", c_oil->oil_ref_count);
+      json_object_int_add(json_source, "oilSize", c_oil->oil_size);
+      json_object_int_add(json_source, "OilInheritedRescan", c_oil->oil_inherited_rescan);
+      json_object_string_add(json_source, "iif", in_ifname);
+      json_oil = NULL;
     }
 
     for (oif_vif_index = 0; oif_vif_index < MAXVIFS; ++oif_vif_index) {
@@ -2980,13 +2996,20 @@ static void show_mroute(struct vty *vty, u_char uj)
         if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_SOURCE)
           json_object_boolean_true_add(json_ifp_out, "protocolSource");
 
+        if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR)
+          json_object_boolean_true_add(json_ifp_out, "protocolInherited");
+
         json_object_string_add(json_ifp_out, "inboundInterface", in_ifname);
         json_object_int_add(json_ifp_out, "iVifI", c_oil->oil.mfcc_parent);
         json_object_string_add(json_ifp_out, "outboundInterface", out_ifname);
         json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
         json_object_int_add(json_ifp_out, "ttl", ttl);
         json_object_string_add(json_ifp_out, "upTime", oif_uptime);
-        json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
+        if (!json_oil) {
+          json_oil = json_object_new_object();
+          json_object_object_add(json_source, "oil", json_oil);
+        }
+        json_object_object_add(json_oil, out_ifname, json_ifp_out);
       } else {
         if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_PIM) {
           strcpy(proto, "PIM");
@@ -3000,6 +3023,10 @@ static void show_mroute(struct vty *vty, u_char uj)
           strcpy(proto, "SRC");
         }
 
+        if (c_oil->oif_flags[oif_vif_index] & PIM_OIF_FLAG_PROTO_STAR) {
+          strcpy(proto, "STAR");
+        }
+
         vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d  %8s%s",
                 src_str,
                 grp_str,
@@ -3035,13 +3062,6 @@ static void show_mroute(struct vty *vty, u_char uj)
 
   /* Print list of static routes */
   for (ALL_LIST_ELEMENTS_RO(qpim_static_route_list, node, s_route)) {
-    char grp_str[INET_ADDRSTRLEN];
-    char src_str[INET_ADDRSTRLEN];
-    char in_ifname[16];
-    char out_ifname[16];
-    int oif_vif_index;
-    struct interface *ifp_in;
-    char proto[100];
     first = 1;
 
     if (!s_route->c_oil.installed)
@@ -3075,14 +3095,8 @@ static void show_mroute(struct vty *vty, u_char uj)
         json_object_object_add(json_group, src_str, json_source);
       }
 
-      /* Find the inbound interface nested under the source, create it if it doesn't exist */
-      json_object_object_get_ex(json_source, in_ifname, &json_ifp_in);
-
-      if (!json_ifp_in) {
-        json_ifp_in = json_object_new_object();
-        json_object_object_add(json_source, in_ifname, json_ifp_in);
-      }
-
+      json_object_string_add(json_source, "iif", in_ifname);
+      json_oil = NULL;
     } else {
       strcpy(proto, "STATIC");
     }
@@ -3116,7 +3130,11 @@ static void show_mroute(struct vty *vty, u_char uj)
         json_object_int_add(json_ifp_out, "oVifI", oif_vif_index);
         json_object_int_add(json_ifp_out, "ttl", ttl);
         json_object_string_add(json_ifp_out, "upTime", oif_uptime);
-        json_object_object_add(json_ifp_in, out_ifname, json_ifp_out);
+        if (!json_oil) {
+          json_oil = json_object_new_object();
+          json_object_object_add(json_source, "oil", json_oil);
+        }
+        json_object_object_add(json_oil, out_ifname, json_ifp_out);
       } else {
         vty_out(vty, "%-15s %-15s %-6s %-10s %-10s %-3d  %8s%s",
                 src_str,
@@ -3161,7 +3179,8 @@ DEFUN (show_ip_mroute,
        "show ip mroute [json]",
        SHOW_STR
        IP_STR
-       MROUTE_STR)
+       MROUTE_STR
+       JSON_STR)
 {
   u_char uj = use_json(argc, argv);
   show_mroute(vty, uj);
@@ -3390,6 +3409,31 @@ pim_rp_cmd_worker (struct vty *vty, const char *rp, const char *group, const cha
   return CMD_SUCCESS;
 }
 
+DEFUN (ip_pim_joinprune_time,
+       ip_pim_joinprune_time_cmd,
+       "ip pim join-prune-interval <60-600>",
+       IP_STR
+       "pim multicast routing\n"
+       "Join Prune Send Interval\n"
+       "Seconds\n")
+{
+  qpim_t_periodic = atoi(argv[3]->arg);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_joinprune_time,
+       no_ip_pim_joinprune_time_cmd,
+       "no ip pim join-prune-interval <60-600>",
+       NO_STR
+       IP_STR
+       "pim multicast routing\n"
+       "Join Prune Send Interval\n"
+       "Seconds\n")
+{
+  qpim_t_periodic = PIM_DEFAULT_T_PERIODIC;
+  return CMD_SUCCESS;
+}
+
 DEFUN (ip_pim_register_suppress,
        ip_pim_register_suppress_cmd,
        "ip pim register-suppress-time <5-60000>",
@@ -3445,7 +3489,8 @@ DEFUN (ip_pim_packets,
        "ip pim packets <1-100>",
        IP_STR
        "pim multicast routing\n"
-       "Number of packets to process at one time per fd\n")
+       "packets to process at one time per fd\n"
+       "Number of packets\n")
 {
   qpim_packet_process = atoi (argv[3]->arg);
   return CMD_SUCCESS;
@@ -3457,22 +3502,53 @@ DEFUN (no_ip_pim_packets,
        NO_STR
        IP_STR
        "pim multicast routing\n"
-       "Number of packets to process at one time per fd\n")
+       "packets to process at one time per fd\n"
+       "Number of packets\n")
 {
   qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
   return CMD_SUCCESS;
 }
 
+DEFUN (ip_pim_v6_secondary,
+       ip_pim_v6_secondary_cmd,
+       "ip pim send-v6-secondary",
+       IP_STR
+       "pim multicast routing\n"
+       "Send v6 secondary addresses\n")
+{
+  pimg->send_v6_secondary = 1;
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ip_pim_v6_secondary,
+       no_ip_pim_v6_secondary_cmd,
+       "no ip pim send-v6-secondary",
+       NO_STR
+       IP_STR
+       "pim multicast routing\n"
+       "Send v6 secondary addresses\n")
+{
+  pimg->send_v6_secondary = 0;
+
+  return CMD_SUCCESS;
+}
+
 DEFUN (ip_pim_rp,
        ip_pim_rp_cmd,
        "ip pim rp A.B.C.D [A.B.C.D/M]",
        IP_STR
        "pim multicast routing\n"
        "Rendevous Point\n"
-       "ip address of RP\n")
+       "ip address of RP\n"
+       "Group Address range to cover\n")
 {
   int idx_ipv4 = 3;
-  return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+
+  if (argc == (idx_ipv4 + 1))
+    return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+  else
+    return pim_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
 }
 
 DEFUN (ip_pim_rp_prefix_list,
@@ -3522,10 +3598,15 @@ DEFUN (no_ip_pim_rp,
        IP_STR
        "pim multicast routing\n"
        "Rendevous Point\n"
-       "ip address of RP\n")
+       "ip address of RP\n"
+       "Group Address range to cover\n")
 {
   int idx_ipv4 = 4;
-  return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+
+  if (argc == (idx_ipv4 + 1))
+    return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, argv[idx_ipv4 + 1]->arg, NULL);
+  else
+    return pim_no_rp_cmd_worker (vty, argv[idx_ipv4]->arg, NULL, NULL);
 }
 
 DEFUN (no_ip_pim_rp_prefix_list,
@@ -3542,31 +3623,171 @@ DEFUN (no_ip_pim_rp_prefix_list,
   return pim_no_rp_cmd_worker (vty, argv[4]->arg, NULL, argv[6]->arg);
 }
 
-DEFUN (ip_multicast_routing,
-       ip_multicast_routing_cmd,
-       "ip multicast-routing",
+static int
+pim_ssm_cmd_worker (struct vty *vty, const char *plist)
+{
+  int result = pim_ssm_range_set (VRF_DEFAULT, plist);
+
+  if (result == PIM_SSM_ERR_NONE)
+    return CMD_SUCCESS;
+
+  switch (result)
+    {
+    case PIM_SSM_ERR_NO_VRF:
+      vty_out (vty, "%% VRF doesn't exist%s", VTY_NEWLINE);
+      break;
+    case PIM_SSM_ERR_DUP:
+      vty_out (vty, "%% duplicate config%s", VTY_NEWLINE);
+      break;
+    default:
+      vty_out (vty, "%% ssm range config failed%s", VTY_NEWLINE);
+    }
+
+  return CMD_WARNING;
+}
+
+DEFUN (ip_pim_ssm_prefix_list,
+       ip_pim_ssm_prefix_list_cmd,
+       "ip pim ssm prefix-list WORD",
        IP_STR
-       "Enable IP multicast forwarding\n")
+       "pim multicast routing\n"
+       "Source Specific Multicast\n"
+       "group range prefix-list filter\n"
+       "Name of a prefix-list\n")
 {
-  pim_mroute_socket_enable();
-  pim_if_add_vif_all();
-  mroute_add_all();
-  static_mroute_add_all();
-  return CMD_SUCCESS;
+  return pim_ssm_cmd_worker (vty, argv[0]->arg);
 }
 
-DEFUN (no_ip_multicast_routing,
-       no_ip_multicast_routing_cmd,
-       "no ip multicast-routing",
+DEFUN (no_ip_pim_ssm_prefix_list,
+       no_ip_pim_ssm_prefix_list_cmd,
+       "no ip pim ssm prefix-list",
        NO_STR
        IP_STR
-       "Global IP configuration subcommands\n"
-       "Enable IP multicast forwarding\n")
+       "pim multicast routing\n"
+       "Source Specific Multicast\n"
+       "group range prefix-list filter\n")
 {
-  mroute_del_all();
-  static_mroute_del_all();
-  pim_if_del_vif_all();
-  pim_mroute_socket_disable();
+  return pim_ssm_cmd_worker (vty, NULL);
+}
+
+DEFUN (no_ip_pim_ssm_prefix_list_name,
+       no_ip_pim_ssm_prefix_list_name_cmd,
+       "no ip pim ssm prefix-list WORD",
+       NO_STR
+       IP_STR
+       "pim multicast routing\n"
+       "Source Specific Multicast\n"
+       "group range prefix-list filter\n"
+       "Name of a prefix-list\n")
+{
+  struct pim_ssm *ssm = pimg->ssm_info;
+
+  if (ssm->plist_name && !strcmp(ssm->plist_name, argv[0]->arg))
+    return pim_ssm_cmd_worker (vty, NULL);
+
+  vty_out (vty, "%% pim ssm prefix-list %s doesn't exist%s",
+           argv[0]->arg, VTY_NEWLINE);
+
+  return CMD_WARNING;
+}
+
+static void
+ip_pim_ssm_show_group_range(struct vty *vty, u_char uj)
+{
+  struct pim_ssm *ssm = pimg->ssm_info;
+  const char *range_str = ssm->plist_name?ssm->plist_name:PIM_SSM_STANDARD_RANGE;
+
+  if (uj)
+    {
+      json_object *json;
+      json = json_object_new_object();
+      json_object_string_add(json, "ssmGroups", range_str);
+      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+      json_object_free(json);
+    }
+  else
+    vty_out(vty, "SSM group range : %s%s", range_str, VTY_NEWLINE);
+}
+
+DEFUN (show_ip_pim_ssm_range,
+       show_ip_pim_ssm_range_cmd,
+       "show ip pim group-type [json]",
+       SHOW_STR
+       IP_STR
+       PIM_STR
+       "PIM group type\n"
+       "JavaScript Object Notation\n")
+{
+  u_char uj = use_json(argc, argv);
+  ip_pim_ssm_show_group_range(vty, uj);
+
+  return CMD_SUCCESS;
+}
+
+static void
+ip_pim_ssm_show_group_type(struct vty *vty, u_char uj, const char *group)
+{
+  struct in_addr group_addr;
+  const char *type_str;
+  int result;
+
+  result = inet_pton(AF_INET, group, &group_addr);
+  if (result <= 0)
+    type_str = "invalid";
+  else
+    {
+      if (pim_is_group_224_4 (group_addr))
+        type_str = pim_is_grp_ssm (group_addr)?"SSM":"ASM";
+      else
+        type_str = "not-multicast";
+    }
+
+  if (uj)
+    {
+      json_object *json;
+      json = json_object_new_object();
+      json_object_string_add(json, "groupType", type_str);
+      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+      json_object_free(json);
+    }
+  else
+    vty_out(vty, "Group type : %s%s", type_str, VTY_NEWLINE);
+}
+
+DEFUN (show_ip_pim_group_type,
+       show_ip_pim_group_type_cmd,
+       "show ip pim group-type A.B.C.D [json]",
+       SHOW_STR
+       IP_STR
+       PIM_STR
+       "multicast group type\n"
+       "group address\n"
+       "JavaScript Object Notation\n")
+{
+  u_char uj = use_json(argc, argv);
+  ip_pim_ssm_show_group_type(vty, uj, argv[0]->arg);
+
+  return CMD_SUCCESS;
+}
+
+DEFUN_HIDDEN (ip_multicast_routing,
+              ip_multicast_routing_cmd,
+              "ip multicast-routing",
+              IP_STR
+              "Enable IP multicast forwarding\n")
+{
+  return CMD_SUCCESS;
+}
+
+DEFUN_HIDDEN (no_ip_multicast_routing,
+              no_ip_multicast_routing_cmd,
+              "no ip multicast-routing",
+              NO_STR
+              IP_STR
+              "Global IP configuration subcommands\n"
+              "Enable IP multicast forwarding\n")
+{
+  vty_out (vty, "Command is Disabled and will be removed in a future version%s",  VTY_NEWLINE);
   return CMD_SUCCESS;
 }
 
@@ -3580,7 +3801,7 @@ DEFUN (ip_ssmpingd,
   int idx_ipv4 = 2;
   int result;
   struct in_addr source_addr;
-  const char *source_str = (argc > idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
+  const char *source_str = (argc == idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
 
   result = inet_pton(AF_INET, source_str, &source_addr);
   if (result <= 0) {
@@ -3610,7 +3831,7 @@ DEFUN (no_ip_ssmpingd,
   int idx_ipv4 = 3;
   int result;
   struct in_addr source_addr;
-  const char *source_str = (argc > idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
+  const char *source_str = (argc == idx_ipv4) ? argv[idx_ipv4]->arg : "0.0.0.0";
 
   result = inet_pton(AF_INET, source_str, &source_addr);
   if (result <= 0) {
@@ -3629,13 +3850,9 @@ DEFUN (no_ip_ssmpingd,
   return CMD_SUCCESS;
 }
 
-DEFUN (interface_ip_igmp,
-       interface_ip_igmp_cmd,
-       "ip igmp",
-       IP_STR
-       IFACE_IGMP_STR)
+static int
+pim_cmd_igmp_start (struct vty *vty, struct interface *ifp)
 {
-  VTY_DECLVAR_CONTEXT(interface, ifp);
   struct pim_interface *pim_ifp;
 
   pim_ifp = ifp->info;
@@ -3658,6 +3875,17 @@ DEFUN (interface_ip_igmp,
   return CMD_SUCCESS;
 }
 
+DEFUN (interface_ip_igmp,
+       interface_ip_igmp_cmd,
+       "ip igmp",
+       IP_STR
+       IFACE_IGMP_STR)
+{
+  VTY_DECLVAR_CONTEXT(interface, ifp);
+
+  return pim_cmd_igmp_start(vty, ifp);
+}
+
 DEFUN (interface_no_ip_igmp,
        interface_no_ip_igmp_cmd,
        "no ip igmp",
@@ -3921,18 +4149,18 @@ DEFUN (interface_ip_igmp_query_interval,
   struct pim_interface *pim_ifp;
   int query_interval;
   int query_interval_dsec;
+  int ret;
 
   pim_ifp = ifp->info;
 
   if (!pim_ifp) {
-    vty_out(vty,
-           "IGMP not enabled on interface %s. Please enable IGMP first.%s",
-           ifp->name,
-           VTY_NEWLINE);
-    return CMD_WARNING;
+    ret = pim_cmd_igmp_start(vty, ifp);
+    if (ret != CMD_SUCCESS)
+      return ret;
+    pim_ifp = ifp->info;
   }
 
-  query_interval = atoi(argv[4]->arg);
+  query_interval = atoi(argv[3]->arg);
   query_interval_dsec = 10 * query_interval;
 
   /*
@@ -4001,7 +4229,7 @@ DEFUN (interface_no_ip_igmp_query_interval,
 
 DEFUN (interface_ip_igmp_version,
        interface_ip_igmp_version_cmd,
-       "ip igmp version <2-3>",
+       "ip igmp version (2-3)",
        IP_STR
        IFACE_IGMP_STR
        "IGMP version\n"
@@ -4010,15 +4238,15 @@ DEFUN (interface_ip_igmp_version,
   VTY_DECLVAR_CONTEXT(interface,ifp);
   struct pim_interface *pim_ifp;
   int igmp_version;
+  int ret;
 
   pim_ifp = ifp->info;
 
   if (!pim_ifp) {
-    vty_out(vty,
-           "IGMP not enabled on interface %s. Please enable IGMP first.%s",
-           ifp->name,
-           VTY_NEWLINE);
-    return CMD_WARNING;
+    ret = pim_cmd_igmp_start(vty, ifp);
+    if (ret != CMD_SUCCESS)
+      return ret;
+    pim_ifp = ifp->info;
   }
 
   igmp_version = atoi(argv[3]->arg);
@@ -4029,7 +4257,7 @@ DEFUN (interface_ip_igmp_version,
 
 DEFUN (interface_no_ip_igmp_version,
        interface_no_ip_igmp_version_cmd,
-       "no ip igmp version <2-3>",
+       "no ip igmp version (2-3)",
        NO_STR
        IP_STR
        IFACE_IGMP_STR
@@ -4063,18 +4291,18 @@ DEFUN (interface_ip_igmp_query_max_response_time,
   VTY_DECLVAR_CONTEXT(interface, ifp);
   struct pim_interface *pim_ifp;
   int query_max_response_time;
+  int ret;
 
   pim_ifp = ifp->info;
 
   if (!pim_ifp) {
-    vty_out(vty,
-           "IGMP not enabled on interface %s. Please enable IGMP first.%s",
-           ifp->name,
-           VTY_NEWLINE);
-    return CMD_WARNING;
+    ret = pim_cmd_igmp_start(vty, ifp);
+    if (ret != CMD_SUCCESS)
+      return ret;
+    pim_ifp = ifp->info;
   }
 
-  query_max_response_time = atoi(argv[4]->arg);
+  query_max_response_time = atoi(argv[3]->arg);
 
   if (query_max_response_time >= pim_ifp->igmp_default_query_interval * 10) {
     vty_out(vty,
@@ -4091,11 +4319,12 @@ DEFUN (interface_ip_igmp_query_max_response_time,
 
 DEFUN (interface_no_ip_igmp_query_max_response_time,
        interface_no_ip_igmp_query_max_response_time_cmd,
-       "no ip igmp query-max-response-time <10-250>",
+       "no ip igmp query-max-response-time (10-250)",
        NO_STR
        IP_STR
        IFACE_IGMP_STR
-       IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR)
+       IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR
+       "Time for response in deci-seconds\n")
 {
   VTY_DECLVAR_CONTEXT(interface, ifp);
   struct pim_interface *pim_ifp;
@@ -4125,15 +4354,15 @@ DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
   struct pim_interface *pim_ifp;
   int query_max_response_time_dsec;
   int default_query_interval_dsec;
+  int ret;
 
   pim_ifp = ifp->info;
 
   if (!pim_ifp) {
-    vty_out(vty,
-           "IGMP not enabled on interface %s. Please enable IGMP first.%s",
-           ifp->name,
-           VTY_NEWLINE);
-    return CMD_WARNING;
+    ret = pim_cmd_igmp_start(vty, ifp);
+    if (ret != CMD_SUCCESS)
+      return ret;
+    pim_ifp = ifp->info;
   }
 
   query_max_response_time_dsec = atoi(argv[4]->arg);
@@ -4235,7 +4464,7 @@ DEFUN (interface_no_ip_pim_drprio,
 }
 
 static int
-pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
+pim_cmd_interface_add (struct interface *ifp)
 {
   struct pim_interface *pim_ifp = ifp->info;
 
@@ -4249,14 +4478,12 @@ pim_cmd_interface_add (struct interface *ifp, enum pim_interface_type itype)
     PIM_IF_DO_PIM(pim_ifp->options);
   }
 
-  pim_ifp->itype = itype;
   pim_if_addr_add_all(ifp);
   pim_if_membership_refresh(ifp);
   return 1;
 }
 
-
-DEFUN (interface_ip_pim_ssm,
+DEFUN_HIDDEN (interface_ip_pim_ssm,
        interface_ip_pim_ssm_cmd,
        "ip pim ssm",
        IP_STR
@@ -4265,11 +4492,12 @@ DEFUN (interface_ip_pim_ssm,
 {
   VTY_DECLVAR_CONTEXT(interface, ifp);
 
-  if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SSM)) {
-    vty_out(vty, "Could not enable PIM SSM on interface%s", VTY_NEWLINE);
+  if (!pim_cmd_interface_add(ifp)) {
+    vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
     return CMD_WARNING;
   }
 
+  vty_out(vty, "WARN: Enabled PIM SM on interface; configure PIM SSM range if needed%s", VTY_NEWLINE);
   return CMD_SUCCESS;
 }
 
@@ -4281,7 +4509,7 @@ DEFUN (interface_ip_pim_sm,
        IFACE_PIM_SM_STR)
 {
   VTY_DECLVAR_CONTEXT(interface, ifp);
-  if (!pim_cmd_interface_add(ifp, PIM_INTERFACE_SM)) {
+  if (!pim_cmd_interface_add(ifp)) {
     vty_out(vty, "Could not enable PIM SM on interface%s", VTY_NEWLINE);
     return CMD_WARNING;
   }
@@ -4317,7 +4545,7 @@ pim_cmd_interface_delete (struct interface *ifp)
   return 1;
 }
 
-DEFUN (interface_no_ip_pim_ssm,
+DEFUN_HIDDEN (interface_no_ip_pim_ssm,
        interface_no_ip_pim_ssm_cmd,
        "no ip pim ssm",
        NO_STR
@@ -4370,7 +4598,7 @@ DEFUN (interface_ip_mroute,
    int               result;
 
    oifname = argv[idx_interface]->arg;
-   oif = if_lookup_by_name(oifname);
+   oif = if_lookup_by_name(oifname, VRF_DEFAULT);
    if (!oif) {
      vty_out(vty, "No such interface name %s%s",
         oifname, VTY_NEWLINE);
@@ -4417,7 +4645,7 @@ DEFUN (interface_ip_mroute_source,
    int               result;
 
    oifname = argv[idx_interface]->arg;
-   oif = if_lookup_by_name(oifname);
+   oif = if_lookup_by_name(oifname, VRF_DEFAULT);
    if (!oif) {
      vty_out(vty, "No such interface name %s%s",
         oifname, VTY_NEWLINE);
@@ -4468,7 +4696,7 @@ DEFUN (interface_no_ip_mroute,
    int               result;
 
    oifname = argv[idx_interface]->arg;
-   oif = if_lookup_by_name(oifname);
+   oif = if_lookup_by_name(oifname, VRF_DEFAULT);
    if (!oif) {
      vty_out(vty, "No such interface name %s%s",
         oifname, VTY_NEWLINE);
@@ -4516,7 +4744,7 @@ DEFUN (interface_no_ip_mroute_source,
    int               result;
 
    oifname = argv[idx_interface]->arg;
-   oif = if_lookup_by_name(oifname);
+   oif = if_lookup_by_name(oifname, VRF_DEFAULT);
    if (!oif) {
      vty_out(vty, "No such interface name %s%s",
         oifname, VTY_NEWLINE);
@@ -4570,7 +4798,7 @@ DEFUN (interface_ip_pim_hello,
 
   pim_ifp->pim_hello_period = strtol(argv[idx_time]->arg, NULL, 10);
 
-  if (argc > idx_hold)
+  if (argc == idx_hold)
     pim_ifp->pim_default_holdtime = strtol(argv[idx_hold]->arg, NULL, 10);
 
   return CMD_SUCCESS;
@@ -4825,22 +5053,9 @@ DEFUN (no_debug_pim_events,
   return CMD_SUCCESS;
 }
 
-
 DEFUN (debug_pim_packets,
        debug_pim_packets_cmd,
-       "debug pim packets",
-       DEBUG_STR
-       DEBUG_PIM_STR
-       DEBUG_PIM_PACKETS_STR)
-{
-    PIM_DO_DEBUG_PIM_PACKETS;
-    vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
-    return CMD_SUCCESS;
-}
-
-DEFUN (debug_pim_packets_filter,
-       debug_pim_packets_filter_cmd,
-       "debug pim packets <hello|joins|register>",
+       "debug pim packets [<hello|joins|register>]",
        DEBUG_STR
        DEBUG_PIM_STR
        DEBUG_PIM_PACKETS_STR
@@ -4848,66 +5063,60 @@ DEFUN (debug_pim_packets_filter,
        DEBUG_PIM_J_P_PACKETS_STR
        DEBUG_PIM_PIM_REG_PACKETS_STR)
 {
-  int idx_hello_join = 3;
-  if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0) 
+  int idx = 0;
+  if (argv_find (argv, argc, "hello", &idx))
     {
       PIM_DO_DEBUG_PIM_HELLO;
       vty_out (vty, "PIM Hello debugging is on%s", VTY_NEWLINE);
     }
-  else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
+  else if (argv_find (argv, argc ,"joins", &idx))
     {
       PIM_DO_DEBUG_PIM_J_P;
       vty_out (vty, "PIM Join/Prune debugging is on%s", VTY_NEWLINE);
     }
-  else if (strncmp(argv[idx_hello_join]->arg,"r",1) == 0)
+  else if (argv_find (argv, argc, "register", &idx))
     {
       PIM_DO_DEBUG_PIM_REG;
       vty_out (vty, "PIM Register debugging is on%s", VTY_NEWLINE);
     }
+  else
+    {
+      PIM_DO_DEBUG_PIM_PACKETS;
+      vty_out (vty, "PIM Packet debugging is on %s", VTY_NEWLINE);
+    }
   return CMD_SUCCESS;
 }
 
 DEFUN (no_debug_pim_packets,
        no_debug_pim_packets_cmd,
-       "no debug pim packets",
-       NO_STR
-       DEBUG_STR
-       DEBUG_PIM_STR
-       DEBUG_PIM_PACKETS_STR
-       DEBUG_PIM_HELLO_PACKETS_STR
-       DEBUG_PIM_J_P_PACKETS_STR)
-{
-  PIM_DONT_DEBUG_PIM_PACKETS;
-  vty_out (vty, "PIM Packet debugging is off %s", VTY_NEWLINE);
-  return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_pim_packets_filter,
-       no_debug_pim_packets_filter_cmd,
-       "no debug pim packets <hello|joins|register>",
+       "no debug pim packets [<hello|joins|register>]",
        NO_STR
        DEBUG_STR
        DEBUG_PIM_STR
        DEBUG_PIM_PACKETS_STR
        DEBUG_PIM_HELLO_PACKETS_STR
-       DEBUG_PIM_J_P_PACKETS_STR)
+       DEBUG_PIM_J_P_PACKETS_STR
+       DEBUG_PIM_PIM_REG_PACKETS_STR)
 {
-  int idx_hello_join = 4;
-  if (strncmp(argv[idx_hello_join]->arg,"h",1) == 0) 
+  int idx = 0;
+  if (argv_find (argv, argc,"hello",&idx))
     {
       PIM_DONT_DEBUG_PIM_HELLO;
       vty_out (vty, "PIM Hello debugging is off %s", VTY_NEWLINE);
     }
-  else if (strncmp(argv[idx_hello_join]->arg,"j",1) == 0)
+  else if (argv_find (argv, argc, "joins", &idx))
     {
       PIM_DONT_DEBUG_PIM_J_P;
       vty_out (vty, "PIM Join/Prune debugging is off %s", VTY_NEWLINE);
     }
-  else if (strncmp (argv[idx_hello_join]->arg, "r", 1) == 0)
+  else if (argv_find (argv, argc, "register", &idx))
     {
       PIM_DONT_DEBUG_PIM_REG;
       vty_out (vty, "PIM Register debugging is off%s", VTY_NEWLINE);
     }
+  else
+    PIM_DONT_DEBUG_PIM_PACKETS;
+
   return CMD_SUCCESS;
 }
 
@@ -5461,9 +5670,10 @@ DEFUN (no_ip_msdp_mesh_group_source,
        CFG_MSDP_STR
        "Delete MSDP mesh-group source\n"
        "mesh group name\n"
+       "mesh group source\n"
        "mesh group local address\n")
 {
-  if (argv[6]->arg)
+  if (argc == 6)
     return ip_no_msdp_mesh_group_cmd_worker(vty, argv[6]->arg);
   else
     return ip_no_msdp_mesh_group_source_cmd_worker(vty, argv[4]->arg);
@@ -5490,6 +5700,7 @@ ip_msdp_show_mesh_group(struct vty *vty, u_char uj)
   enum pim_msdp_peer_state state;
   json_object *json = NULL;
   json_object *json_mg_row = NULL;
+  json_object *json_members = NULL;
   json_object *json_row = NULL;
 
   if (!mg) {
@@ -5524,7 +5735,11 @@ ip_msdp_show_mesh_group(struct vty *vty, u_char uj)
       json_row = json_object_new_object();
       json_object_string_add(json_row, "member", mbr_str);
       json_object_string_add(json_row, "state", state_str);
-      json_object_object_add(json_mg_row, mbr_str, json_row);
+      if (!json_members) {
+        json_members = json_object_new_object();
+        json_object_object_add(json_mg_row, "members", json_members);
+      }
+      json_object_object_add(json_members, mbr_str, json_row);
     } else {
       vty_out(vty, "  %-15s  %11s%s",
           mbr_str, state_str, VTY_NEWLINE);
@@ -5703,7 +5918,10 @@ DEFUN (show_ip_msdp_peer_detail,
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (argv[4]->arg)
+  if (uj)
+    argc--;
+
+  if (argc == 4)
     ip_msdp_show_peers_detail(vty, argv[4]->arg, uj);
   else
     ip_msdp_show_peers(vty, uj);
@@ -5945,18 +6163,22 @@ ip_msdp_show_sa_sg(struct vty *vty, const char *src, const char *grp, u_char uj)
 
 DEFUN (show_ip_msdp_sa_sg,
        show_ip_msdp_sa_sg_cmd,
-       "show ip msdp sa [A.B.C.D] [A.B.C.D] [json]",
+       "show ip msdp sa [A.B.C.D [A.B.C.D]] [json]",
        SHOW_STR
        IP_STR
        MSDP_STR
        "MSDP active-source information\n"
        "source or group ip\n"
+       "group ip\n"
        "JavaScript Object Notation\n")
 {
   u_char uj = use_json(argc, argv);
-  if (argv[5]->arg)
+  if (uj)
+    argc--;
+
+  if (argc == 5)
     ip_msdp_show_sa_sg(vty, argv[4]->arg, argv[5]->arg, uj);
-  else if (argv[4]->arg)
+  else if (argc == 4)
     ip_msdp_show_sa_addr(vty, argv[4]->arg, uj);
   else
     ip_msdp_show_sa(vty, uj);
@@ -5978,12 +6200,19 @@ void pim_cmd_init()
   install_element (CONFIG_NODE, &no_ip_pim_rp_cmd);
   install_element (CONFIG_NODE, &ip_pim_rp_prefix_list_cmd);
   install_element (CONFIG_NODE, &no_ip_pim_rp_prefix_list_cmd);
+  install_element (CONFIG_NODE, &no_ip_pim_ssm_prefix_list_cmd);
+  install_element (CONFIG_NODE, &no_ip_pim_ssm_prefix_list_name_cmd);
+  install_element (CONFIG_NODE, &ip_pim_ssm_prefix_list_cmd);
   install_element (CONFIG_NODE, &ip_pim_register_suppress_cmd);
   install_element (CONFIG_NODE, &no_ip_pim_register_suppress_cmd);
+  install_element (CONFIG_NODE, &ip_pim_joinprune_time_cmd);
+  install_element (CONFIG_NODE, &no_ip_pim_joinprune_time_cmd);
   install_element (CONFIG_NODE, &ip_pim_keep_alive_cmd);
   install_element (CONFIG_NODE, &no_ip_pim_keep_alive_cmd);
   install_element (CONFIG_NODE, &ip_pim_packets_cmd);
   install_element (CONFIG_NODE, &no_ip_pim_packets_cmd);
+  install_element (CONFIG_NODE, &ip_pim_v6_secondary_cmd);
+  install_element (CONFIG_NODE, &no_ip_pim_v6_secondary_cmd);
   install_element (CONFIG_NODE, &ip_ssmpingd_cmd);
   install_element (CONFIG_NODE, &no_ip_ssmpingd_cmd); 
   install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
@@ -6069,9 +6298,7 @@ void pim_cmd_init()
   install_element (ENABLE_NODE, &debug_pim_events_cmd);
   install_element (ENABLE_NODE, &no_debug_pim_events_cmd);
   install_element (ENABLE_NODE, &debug_pim_packets_cmd);
-  install_element (ENABLE_NODE, &debug_pim_packets_filter_cmd);
   install_element (ENABLE_NODE, &no_debug_pim_packets_cmd);
-  install_element (ENABLE_NODE, &no_debug_pim_packets_filter_cmd);
   install_element (ENABLE_NODE, &debug_pim_packetdump_send_cmd);
   install_element (ENABLE_NODE, &no_debug_pim_packetdump_send_cmd);
   install_element (ENABLE_NODE, &debug_pim_packetdump_recv_cmd);
@@ -6111,9 +6338,7 @@ void pim_cmd_init()
   install_element (CONFIG_NODE, &debug_pim_events_cmd);
   install_element (CONFIG_NODE, &no_debug_pim_events_cmd);
   install_element (CONFIG_NODE, &debug_pim_packets_cmd);
-  install_element (CONFIG_NODE, &debug_pim_packets_filter_cmd);
   install_element (CONFIG_NODE, &no_debug_pim_packets_cmd);
-  install_element (CONFIG_NODE, &no_debug_pim_packets_filter_cmd);
   install_element (CONFIG_NODE, &debug_pim_trace_cmd);
   install_element (CONFIG_NODE, &no_debug_pim_trace_cmd);
   install_element (CONFIG_NODE, &debug_ssmpingd_cmd);
@@ -6129,8 +6354,6 @@ void pim_cmd_init()
   install_element (CONFIG_NODE, &debug_msdp_packets_cmd);
   install_element (CONFIG_NODE, &no_debug_msdp_packets_cmd);
   install_element (CONFIG_NODE, &undebug_msdp_packets_cmd);
-  install_element (CONFIG_NODE, &ip_msdp_peer_cmd);
-  install_element (CONFIG_NODE, &no_ip_msdp_peer_cmd);
   install_element (CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
   install_element (CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
   install_element (CONFIG_NODE, &ip_msdp_mesh_group_source_cmd);
@@ -6139,6 +6362,8 @@ void pim_cmd_init()
   install_element (VIEW_NODE, &show_ip_msdp_sa_detail_cmd);
   install_element (VIEW_NODE, &show_ip_msdp_sa_sg_cmd);
   install_element (VIEW_NODE, &show_ip_msdp_mesh_group_cmd);
+  install_element (VIEW_NODE, &show_ip_pim_ssm_range_cmd);
+  install_element (VIEW_NODE, &show_ip_pim_group_type_cmd);
   install_element (INTERFACE_NODE, &interface_pim_use_source_cmd);
   install_element (INTERFACE_NODE, &interface_no_pim_use_source_cmd);
 }