]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_cmd.c
Merge pull request #291 from AnuradhaKaruppiah/pim-ssm
[mirror_frr.git] / pimd / pim_cmd.c
index 016ba3e4512b9d2e233f2b14e5f4a31938c142df..3c5a16ec68d38233641c287ca19fc573af8284bd 100644 (file)
@@ -54,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,
@@ -1168,7 +1169,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);
 
@@ -1187,7 +1189,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,
@@ -1422,6 +1424,14 @@ 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, "%-9d %-15s  %-15s  %-7s  ",
@@ -1643,6 +1653,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;
@@ -1667,6 +1715,7 @@ 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));
@@ -1690,6 +1739,14 @@ static void pim_show_upstream(struct vty *vty, u_char uj)
     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);
 
@@ -1703,7 +1760,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);
@@ -1717,7 +1776,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,
@@ -3540,6 +3599,153 @@ DEFUN (no_ip_pim_rp_prefix_list,
   return pim_no_rp_cmd_worker (vty, argv[4]->arg, NULL, argv[6]->arg);
 }
 
+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
+       "pim multicast routing\n"
+       "Source Specific Multicast\n"
+       "group range prefix-list filter\n"
+       "Name of a prefix-list\n")
+{
+  return pim_ssm_cmd_worker (vty, argv[0]->arg);
+}
+
+DEFUN (no_ip_pim_ssm_prefix_list,
+       no_ip_pim_ssm_prefix_list_cmd,
+       "no ip pim ssm prefix-list",
+       NO_STR
+       IP_STR
+       "pim multicast routing\n"
+       "Source Specific Multicast\n"
+       "group range prefix-list filter\n")
+{
+  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",
@@ -4234,7 +4440,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;
 
@@ -4248,14 +4454,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
@@ -4264,11 +4468,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;
 }
 
@@ -4280,7 +4485,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;
   }
@@ -4316,7 +4521,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
@@ -4369,7 +4574,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);
@@ -4416,7 +4621,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);
@@ -4467,7 +4672,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);
@@ -4515,7 +4720,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);
@@ -5971,6 +6176,9 @@ 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);
@@ -6128,6 +6336,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);
 }