]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #435 from chiragshah6/pim_dev
authorJafar Al-Gharaibeh <Jafaral@users.noreply.github.com>
Tue, 9 May 2017 15:50:56 +0000 (10:50 -0500)
committerGitHub <noreply@github.com>
Tue, 9 May 2017 15:50:56 +0000 (10:50 -0500)
pimd: Introduce show command for protocol counters

pimd/pim_assert.c
pimd/pim_cmd.c
pimd/pim_iface.h
pimd/pim_join.c
pimd/pim_register.c

index f2bfb846dda46ee402e5e6cb8b30f65e65788892..17f5fcfe0f9a321b872ea3940e1abf970b9d4611 100644 (file)
@@ -230,6 +230,7 @@ int pim_assert_recv(struct interface *ifp,
   int offset;
   uint8_t *curr;
   int curr_size;
+  struct pim_interface *pim_ifp = NULL;
 
   on_trace(__PRETTY_FUNCTION__, ifp, src_addr);
 
@@ -311,6 +312,10 @@ int pim_assert_recv(struct interface *ifp,
 
   msg_metric.ip_address = src_addr;
 
+  pim_ifp = ifp->info;
+  zassert(pim_ifp);
+  ++pim_ifp->pim_ifstat_assert_recv;
+
   return dispatch_assert(ifp,
                         msg_source_addr.u.prefix4,
                         sg.grp,
@@ -473,6 +478,7 @@ static int pim_assert_do(struct pim_ifchannel *ch,
               metric.route_metric,
               PIM_FORCE_BOOLEAN(metric.rpt_bit_flag));
   }
+  ++pim_ifp->pim_ifstat_assert_send;
 
   if (pim_msg_send(pim_ifp->pim_sock_fd,
                   pim_ifp->primary_address,
index e476a32fb03e5912756c6dc53489783e2e43e928..c6e9ae0c376811daed2629d85489b72cba872803 100644 (file)
@@ -1123,6 +1123,163 @@ static void pim_show_interfaces(struct vty *vty, u_char uj)
   json_object_free(json);
 }
 
+static void pim_show_interface_traffic (struct vty *vty, u_char uj)
+{
+  struct interface *ifp = NULL;
+  struct pim_interface *pim_ifp = NULL;
+  struct listnode *node = NULL;
+  json_object *json = NULL;
+  json_object *json_row = NULL;
+
+  if (uj)
+    json = json_object_new_object ();
+  else
+    {
+      vty_out (vty, "%s", VTY_NEWLINE);
+      vty_out (vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
+               "    HELLO", "    JOIN", "   PRUNE", "   REGISTER",
+               "  REGISTER-STOP", "  ASSERT", VTY_NEWLINE);
+      vty_out (vty,
+               "%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
+               "", "      Rx/Tx", "     Rx/Tx", "    Rx/Tx", "    Rx/Tx",
+               "     Rx/Tx", "    Rx/Tx", VTY_NEWLINE);
+      vty_out (vty,
+           "---------------------------------------------------------------------------------------------------------------%s",
+           VTY_NEWLINE);
+    }
+
+  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
+    {
+      pim_ifp = ifp->info;
+
+      if (!pim_ifp)
+        continue;
+
+      if (pim_ifp->pim_sock_fd < 0)
+        continue;
+      if (uj)
+        {
+          json_row = json_object_new_object ();
+          json_object_pim_ifp_add (json_row, ifp);
+          json_object_int_add (json_row, "helloRx", pim_ifp->pim_ifstat_hello_recv);
+          json_object_int_add (json_row, "helloTx", pim_ifp->pim_ifstat_hello_sent);
+          json_object_int_add (json_row, "joinRx", pim_ifp->pim_ifstat_join_recv);
+          json_object_int_add (json_row, "joinTx", pim_ifp->pim_ifstat_join_send);
+          json_object_int_add (json_row, "registerRx", pim_ifp->pim_ifstat_reg_recv);
+          json_object_int_add (json_row, "registerTx", pim_ifp->pim_ifstat_reg_recv);
+          json_object_int_add (json_row, "registerStopRx", pim_ifp->pim_ifstat_reg_stop_recv);
+          json_object_int_add (json_row, "registerStopTx", pim_ifp->pim_ifstat_reg_stop_send);
+          json_object_int_add (json_row, "assertRx", pim_ifp->pim_ifstat_assert_recv);
+          json_object_int_add (json_row, "assertTx", pim_ifp->pim_ifstat_assert_send);
+
+          json_object_object_add (json, ifp->name, json_row);
+        }
+      else
+        {
+          vty_out (vty,
+               "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
+               ifp->name, pim_ifp->pim_ifstat_hello_recv,
+               pim_ifp->pim_ifstat_hello_sent, pim_ifp->pim_ifstat_join_recv,
+               pim_ifp->pim_ifstat_join_send, pim_ifp->pim_ifstat_prune_recv,
+               pim_ifp->pim_ifstat_prune_send, pim_ifp->pim_ifstat_reg_recv,
+               pim_ifp->pim_ifstat_reg_send,
+               pim_ifp->pim_ifstat_reg_stop_recv,
+               pim_ifp->pim_ifstat_reg_stop_send,
+               pim_ifp->pim_ifstat_assert_recv,
+               pim_ifp->pim_ifstat_assert_send, VTY_NEWLINE);
+        }
+    }
+  if (uj)
+    {
+      vty_out (vty, "%s%s", json_object_to_json_string_ext (json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+      json_object_free (json);
+    }
+}
+
+static void pim_show_interface_traffic_single (struct vty *vty, const char *ifname, u_char uj)
+{
+  struct interface *ifp = NULL;
+  struct pim_interface *pim_ifp = NULL;
+  struct listnode *node = NULL;
+  json_object *json = NULL;
+  json_object *json_row = NULL;
+  uint8_t found_ifname = 0;
+
+  if (uj)
+    json = json_object_new_object ();
+  else
+    {
+      vty_out (vty, "%s", VTY_NEWLINE);
+      vty_out (vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
+               "    HELLO", "    JOIN", "   PRUNE", "   REGISTER",
+               "  REGISTER-STOP", "  ASSERT", VTY_NEWLINE);
+      vty_out (vty,
+               "%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
+               "", "      Rx/Tx", "     Rx/Tx", "    Rx/Tx", "    Rx/Tx",
+               "     Rx/Tx", "    Rx/Tx", VTY_NEWLINE);
+      vty_out (vty,
+           "---------------------------------------------------------------------------------------------------------------%s",
+           VTY_NEWLINE);
+    }
+
+  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
+    {
+      if (strcmp (ifname, ifp->name))
+        continue;
+
+      pim_ifp = ifp->info;
+
+      if (!pim_ifp)
+        continue;
+
+      if (pim_ifp->pim_sock_fd < 0)
+        continue;
+
+      found_ifname = 1;
+      if (uj)
+        {
+          json_row = json_object_new_object ();
+          json_object_pim_ifp_add (json_row, ifp);
+          json_object_int_add (json_row, "helloRx", pim_ifp->pim_ifstat_hello_recv);
+          json_object_int_add (json_row, "helloTx", pim_ifp->pim_ifstat_hello_sent);
+          json_object_int_add (json_row, "joinRx", pim_ifp->pim_ifstat_join_recv);
+          json_object_int_add (json_row, "joinTx", pim_ifp->pim_ifstat_join_send);
+          json_object_int_add (json_row, "registerRx", pim_ifp->pim_ifstat_reg_recv);
+          json_object_int_add (json_row, "registerTx", pim_ifp->pim_ifstat_reg_recv);
+          json_object_int_add (json_row, "registerStopRx", pim_ifp->pim_ifstat_reg_stop_recv);
+          json_object_int_add (json_row, "registerStopTx", pim_ifp->pim_ifstat_reg_stop_send);
+          json_object_int_add (json_row, "assertRx", pim_ifp->pim_ifstat_assert_recv);
+          json_object_int_add (json_row, "assertTx", pim_ifp->pim_ifstat_assert_send);
+
+          json_object_object_add (json, ifp->name, json_row);
+        }
+      else
+        {
+          vty_out (vty,
+               "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
+               ifp->name, pim_ifp->pim_ifstat_hello_recv,
+               pim_ifp->pim_ifstat_hello_sent, pim_ifp->pim_ifstat_join_recv,
+               pim_ifp->pim_ifstat_join_send, pim_ifp->pim_ifstat_prune_recv,
+               pim_ifp->pim_ifstat_prune_send, pim_ifp->pim_ifstat_reg_recv,
+               pim_ifp->pim_ifstat_reg_send,
+               pim_ifp->pim_ifstat_reg_stop_recv,
+               pim_ifp->pim_ifstat_reg_stop_send,
+               pim_ifp->pim_ifstat_assert_recv,
+               pim_ifp->pim_ifstat_assert_send, VTY_NEWLINE);
+        }
+    }
+  if (uj)
+    {
+      vty_out (vty, "%s%s", json_object_to_json_string_ext (json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
+      json_object_free (json);
+    }
+  else
+    {
+      if (!found_ifname)
+        vty_out (vty, "%% No such interface%s", VTY_NEWLINE);
+    }
+}
+
 static void pim_show_join(struct vty *vty, u_char uj)
 {
   struct pim_interface *pim_ifp;
@@ -2497,6 +2654,45 @@ DEFUN (clear_ip_pim_interfaces,
   return CMD_SUCCESS;
 }
 
+DEFUN (clear_ip_pim_interface_traffic,
+       clear_ip_pim_interface_traffic_cmd,
+       "clear ip pim interface traffic",
+       "Reset functions\n"
+       "IP information\n"
+       "PIM clear commands\n"
+       "Reset PIM interfaces\n"
+       "Reset Protocol Packet counters\n")
+{
+  struct listnode  *ifnode = NULL;
+  struct listnode  *ifnextnode = NULL;
+  struct interface *ifp = NULL;
+  struct pim_interface *pim_ifp = NULL;
+
+  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp))
+    {
+      pim_ifp = ifp->info;
+
+      if (!pim_ifp)
+        continue;
+
+      pim_ifp->pim_ifstat_hello_recv = 0;
+      pim_ifp->pim_ifstat_hello_sent = 0;
+      pim_ifp->pim_ifstat_join_recv = 0;
+      pim_ifp->pim_ifstat_join_send = 0;
+      pim_ifp->pim_ifstat_prune_recv = 0;
+      pim_ifp->pim_ifstat_prune_send = 0;
+      pim_ifp->pim_ifstat_reg_recv = 0;
+      pim_ifp->pim_ifstat_reg_send = 0;
+      pim_ifp->pim_ifstat_reg_stop_recv = 0;
+      pim_ifp->pim_ifstat_reg_stop_send = 0;
+      pim_ifp->pim_ifstat_assert_recv = 0;
+      pim_ifp->pim_ifstat_assert_send = 0;
+
+    }
+
+  return CMD_SUCCESS;
+}
+
 DEFUN (clear_ip_pim_oil,
        clear_ip_pim_oil_cmd,
        "clear ip pim oil",
@@ -2883,7 +3079,7 @@ DEFUN (show_ip_pim_nexthop_lookup,
   char nexthop_addr_str[PREFIX_STRLEN];
   char grp_str[PREFIX_STRLEN];
 
-  addr_str = (const char *)argv[0];
+  addr_str = argv[4]->arg;
   result = inet_pton (AF_INET, addr_str, &src_addr);
   if (result <= 0)
     {
@@ -2898,7 +3094,7 @@ DEFUN (show_ip_pim_nexthop_lookup,
       return CMD_WARNING;
     }
 
-  addr_str1 = (const char *)argv[1];
+  addr_str1 = argv[5]->arg;
   result = inet_pton (AF_INET, addr_str1, &grp_addr);
   if (result <= 0)
     {
@@ -2942,6 +3138,28 @@ DEFUN (show_ip_pim_nexthop_lookup,
   return CMD_SUCCESS;
 }
 
+DEFUN (show_ip_pim_interface_traffic,
+       show_ip_pim_interface_traffic_cmd,
+       "show ip pim interface traffic [WORD] [json]",
+       SHOW_STR
+       IP_STR
+       PIM_STR
+       "PIM interface information\n"
+       "Protocol Packet counters\n"
+       "Interface name\n"
+       "JavaScript Object Notation\n")
+{
+  u_char uj = use_json (argc, argv);
+  int idx = 0;
+
+  if (argv_find(argv, argc, "WORD", &idx))
+    pim_show_interface_traffic_single (vty, argv[idx]->arg, uj);
+  else
+    pim_show_interface_traffic (vty, uj);
+
+  return CMD_SUCCESS;
+}
+
 static void show_multicast_interfaces(struct vty *vty)
 {
   struct listnode  *node;
@@ -6578,6 +6796,7 @@ void pim_cmd_init()
   install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
   install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
   install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
+  install_element (VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
   install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
   install_element (VIEW_NODE, &show_ip_pim_join_cmd);
   install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
@@ -6602,6 +6821,7 @@ void pim_cmd_init()
   install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
   install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
   install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
+  install_element (ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
   install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
 
   install_element (ENABLE_NODE, &debug_igmp_cmd);
index c42c6910676dea57148cf9720268e59f669fed31..3c353b04975e9a9158b0295095936babf8c11b6b 100644 (file)
@@ -118,6 +118,16 @@ struct pim_interface {
   uint32_t       pim_ifstat_hello_sendfail;
   uint32_t       pim_ifstat_hello_recv;
   uint32_t       pim_ifstat_hello_recvfail;
+  uint32_t       pim_ifstat_join_recv;
+  uint32_t       pim_ifstat_join_send;
+  uint32_t       pim_ifstat_prune_recv;
+  uint32_t       pim_ifstat_prune_send;
+  uint32_t       pim_ifstat_reg_recv;
+  uint32_t       pim_ifstat_reg_send;
+  uint32_t       pim_ifstat_reg_stop_recv;
+  uint32_t       pim_ifstat_reg_stop_send;
+  uint32_t       pim_ifstat_assert_recv;
+  uint32_t       pim_ifstat_assert_send;
 };
 
 extern struct interface *pim_regiface;
index 828781a4670b511376491009154f30db7b00680d..ae7fedc62bef5257f5d84f8b3d9641bd93967ac2 100644 (file)
@@ -59,6 +59,8 @@ static void recv_join(struct interface *ifp,
                      struct prefix_sg *sg,
                      uint8_t source_flags)
 {
+  struct pim_interface *pim_ifp = NULL;
+
   if (PIM_DEBUG_PIM_TRACE) {
     char up_str[INET_ADDRSTRLEN];
     char neigh_str[INET_ADDRSTRLEN];
@@ -72,6 +74,11 @@ static void recv_join(struct interface *ifp,
              up_str, holdtime, neigh_str, ifp->name);
   }
 
+  pim_ifp = ifp->info;
+  zassert(pim_ifp);
+
+  ++pim_ifp->pim_ifstat_join_recv;
+
   /*
    * If the RPT and WC are set it's a (*,G)
    * and the source is the RP
@@ -104,6 +111,8 @@ static void recv_prune(struct interface *ifp,
                       struct prefix_sg *sg,
                       uint8_t source_flags)
 {
+  struct pim_interface *pim_ifp = NULL;
+
   if (PIM_DEBUG_PIM_TRACE) {
     char up_str[INET_ADDRSTRLEN];
     char neigh_str[INET_ADDRSTRLEN];
@@ -117,6 +126,11 @@ static void recv_prune(struct interface *ifp,
              up_str, holdtime, neigh_str, ifp->name);
   }
 
+  pim_ifp = ifp->info;
+  zassert(pim_ifp);
+
+  ++pim_ifp->pim_ifstat_prune_recv;
+
   if ((source_flags & PIM_RPT_BIT_MASK) &&
       (source_flags & PIM_WILDCARD_BIT_MASK))
     {
@@ -502,6 +516,9 @@ int pim_joinprune_send(struct pim_rpf *rpf,
       packet_size += group_size;
       pim_msg_build_jp_groups (grp, group, group_size);
 
+      pim_ifp->pim_ifstat_join_send += ntohs(grp->joins);
+      pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes);
+
       grp = (struct pim_jp_groups *)curr_ptr;
       if (packet_left < sizeof (struct pim_jp_groups) || msg->num_groups == 255)
         {
index 8dc179c1444ccec91166b93a72e5ee3a35c5de33..f23993625d7e3faf3bd24dc007aeb1c1f568158a 100644 (file)
@@ -110,6 +110,7 @@ pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg,
                      __PRETTY_FUNCTION__, ifp->name);
        }
     }
+  ++pinfo->pim_ifstat_reg_stop_send;
 }
 
 int
@@ -205,6 +206,8 @@ pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct
 
   pim_msg_build_header(buffer, buf_size + PIM_MSG_REGISTER_LEN, PIM_MSG_TYPE_REGISTER);
 
+  ++pinfo->pim_ifstat_reg_send;
+
   if (pim_msg_send(pinfo->pim_sock_fd,
                   src,
                   rpg->rpf_addr.u.prefix4,
@@ -274,6 +277,7 @@ pim_register_recv (struct interface *ifp,
   struct prefix_sg sg;
   uint32_t *bits;
   int i_am_rp = 0;
+  struct pim_interface *pim_ifp = NULL;
 
 #define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
   ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
@@ -289,6 +293,10 @@ pim_register_recv (struct interface *ifp,
     return 0;
   }
 
+  pim_ifp = ifp->info;
+  zassert(pim_ifp);
+  ++pim_ifp->pim_ifstat_reg_recv;
+
   /*
    * Please note this is not drawn to get the correct bit/data size
    *