mroute routers in the stats segment 46/15046/3
authorNeale Ranns <nranns@cisco.com>
Fri, 7 Sep 2018 16:37:07 +0000 (09:37 -0700)
committerDamjan Marion <dmarion@me.com>
Mon, 1 Oct 2018 09:43:22 +0000 (09:43 +0000)
Change-Id: I798e4fb6470ae9e763f8de1c290ff0fc3c0b7f9e
Signed-off-by: Neale Ranns <nranns@cisco.com>
src/vnet/dpo/replicate_dpo.c
src/vnet/fib/fib_table.c
src/vnet/ip/ip.api
src/vnet/ip/ip_api.c
src/vnet/mfib/mfib_entry.c
src/vnet/mfib/mfib_entry.h
test/test_ip_mcast.py
test/vpp_ip_route.py

index 95d7f97..8c8206c 100644 (file)
@@ -59,7 +59,12 @@ replicate_t *replicate_pool;
 /**
  * The one instance of replicate main
  */
-replicate_main_t replicate_main;
+replicate_main_t replicate_main = {
+    .repm_counters = {
+        .name = "mroutes",
+        .stat_segment_name = "/net/mroute",
+    },
+};
 
 static inline index_t
 replicate_get_index (const replicate_t *rep)
index 47f2011..69746d9 100644 (file)
@@ -886,8 +886,8 @@ fib_table_entry_delete_index (fib_node_index_t fib_entry_index,
 }
 
 u32
-fib_table_entry_get_stats_index(u32 fib_index,
-                                const fib_prefix_t *prefix)
+fib_table_entry_get_stats_index (u32 fib_index,
+                                 const fib_prefix_t *prefix)
 {
     return (fib_entry_get_stats_index(
                 fib_table_lookup_exact_match(fib_index, prefix)));
index 7c7f656..71ad1c1 100644 (file)
@@ -440,7 +440,7 @@ define ip_add_del_route_reply
     @param next_hop_afi - Use dpo_proto_t
     FIXME
 */
-autoreply define ip_mroute_add_del
+define ip_mroute_add_del
 {
   u32 client_index;
   u32 context;
@@ -460,6 +460,13 @@ autoreply define ip_mroute_add_del
   u8 nh_address[16];
 };
 
+define ip_mroute_add_del_reply
+{
+  u32 context;
+  i32 retval;
+  u32 stats_index;
+};
+
 /** \brief Dump IP multicast fib table
     @param client_index - opaque cookie to identify the sender
 */
@@ -487,6 +494,7 @@ manual_endian manual_print define ip_mfib_details
   u8  grp_address[4];
   u8  src_address[4];
   u32 count;
+  u32 stats_index;
   vl_api_fib_path_t path[count];
 };
 
index 477090d..5dbc02d 100644 (file)
@@ -1203,7 +1203,7 @@ add_del_mroute_check (fib_protocol_t table_proto,
   return (0);
 }
 
-static int
+static fib_node_index_t
 mroute_add_del_handler (u8 is_add,
                        u8 is_local,
                        u32 fib_index,
@@ -1214,6 +1214,8 @@ mroute_add_del_handler (u8 is_add,
                        u32 next_hop_sw_if_index,
                        ip46_address_t * nh, u32 itf_flags, u32 bier_imp)
 {
+  fib_node_index_t mfib_entry_index = ~0;
+
   stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
 
   fib_route_path_t path = {
@@ -1232,15 +1234,17 @@ mroute_add_del_handler (u8 is_add,
     }
   else if (!is_local && ~0 == next_hop_sw_if_index)
     {
-      mfib_table_entry_update (fib_index, prefix,
-                              MFIB_SOURCE_API, rpf_id, entry_flags);
+      mfib_entry_index = mfib_table_entry_update (fib_index, prefix,
+                                                 MFIB_SOURCE_API,
+                                                 rpf_id, entry_flags);
       goto done;
     }
 
   if (is_add)
     {
-      mfib_table_entry_path_update (fib_index, prefix,
-                                   MFIB_SOURCE_API, &path, itf_flags);
+      mfib_entry_index = mfib_table_entry_path_update (fib_index, prefix,
+                                                      MFIB_SOURCE_API,
+                                                      &path, itf_flags);
     }
   else
     {
@@ -1250,12 +1254,14 @@ mroute_add_del_handler (u8 is_add,
 
 done:
   stats_dsunlock ();
-  return (0);
+  return (mfib_entry_index);
 }
 
 static int
-api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp)
+api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp,
+                             u32 * stats_index)
 {
+  fib_node_index_t mfib_entry_index;
   fib_protocol_t fproto;
   dpo_proto_t nh_proto;
   ip46_address_t nh;
@@ -1295,32 +1301,43 @@ api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp)
       clib_memcpy (&nh.ip6, mp->nh_address, sizeof (nh.ip6));
     }
 
-  return (mroute_add_del_handler (mp->is_add,
-                                 mp->is_local,
-                                 fib_index, &pfx,
-                                 nh_proto,
-                                 ntohl (mp->entry_flags),
-                                 ntohl (mp->rpf_id),
-                                 ntohl (mp->next_hop_sw_if_index),
-                                 &nh,
-                                 ntohl (mp->itf_flags),
-                                 ntohl (mp->bier_imp)));
+  mfib_entry_index = mroute_add_del_handler (mp->is_add,
+                                            mp->is_local,
+                                            fib_index, &pfx,
+                                            nh_proto,
+                                            ntohl (mp->entry_flags),
+                                            ntohl (mp->rpf_id),
+                                            ntohl (mp->next_hop_sw_if_index),
+                                            &nh,
+                                            ntohl (mp->itf_flags),
+                                            ntohl (mp->bier_imp));
+
+  if (~0 != mfib_entry_index)
+    *stats_index = mfib_entry_get_stats_index (mfib_entry_index);
+
+  return (rv);
 }
 
 void
 vl_api_ip_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp)
 {
   vl_api_ip_mroute_add_del_reply_t *rmp;
+  vnet_main_t *vnm;
+  u32 stats_index;
   int rv;
-  vnet_main_t *vnm = vnet_get_main ();
 
+  vnm = vnet_get_main ();
   vnm->api_errno = 0;
+  stats_index = ~0;
 
-  rv = api_mroute_add_del_t_handler (mp);
+  rv = api_mroute_add_del_t_handler (mp, &stats_index);
 
-  rv = (rv == 0) ? vnm->api_errno : rv;
-
-  REPLY_MACRO (VL_API_IP_MROUTE_ADD_DEL_REPLY);
+  /* *INDENT-OFF* */
+  REPLY_MACRO2 (VL_API_IP_MROUTE_ADD_DEL_REPLY,
+  ({
+    rmp->stats_index = htonl (stats_index);
+  }));
+  /* *INDENT-ON* */
 }
 
 static void
index a88f375..7427334 100644 (file)
@@ -1106,6 +1106,16 @@ mfib_entry_last_lock_gone (fib_node_t *node)
     pool_put(mfib_entry_pool, mfib_entry);
 }
 
+u32
+mfib_entry_get_stats_index (fib_node_index_t fib_entry_index)
+{
+    mfib_entry_t *mfib_entry;
+
+    mfib_entry = mfib_entry_get(fib_entry_index);
+
+    return (mfib_entry->mfe_rep.dpoi_index);
+}
+
 /*
  * mfib_entry_back_walk_notify
  *
index a1d5acf..880c1e2 100644 (file)
@@ -132,6 +132,7 @@ extern void mfib_entry_get_prefix(fib_node_index_t fib_entry_index,
 extern u32 mfib_entry_get_fib_index(fib_node_index_t fib_entry_index);
 extern int mfib_entry_is_sourced(fib_node_index_t fib_entry_index,
                                  mfib_source_t source);
+extern u32 mfib_entry_get_stats_index(fib_node_index_t fib_entry_index);
 
 extern const dpo_id_t*mfib_entry_contribute_ip_forwarding(
     fib_node_index_t mfib_entry_index);
index 64eb304..1a39e9a 100644 (file)
@@ -273,6 +273,9 @@ class TestIPMcast(VppTestCase):
         self.pg_enable_capture(self.pg_interfaces)
         self.pg_start()
 
+        self.assertEqual(route_1_1_1_1_232_1_1_1.get_stats()['packets'],
+                         len(tx))
+
         # We expect replications on Pg1->7
         self.verify_capture_ip4(self.pg1, tx)
         self.verify_capture_ip4(self.pg2, tx)
@@ -299,6 +302,9 @@ class TestIPMcast(VppTestCase):
         self.verify_capture_ip4(self.pg1, tx)
         self.verify_capture_ip4(self.pg2, tx)
 
+        self.assertEqual(route_1_1_1_1_232_1_1_1.get_stats()['packets'],
+                         2*len(tx))
+
         # no replications on Pg0
         self.pg0.assert_nothing_captured(
             remark="IP multicast packets forwarded on PG0")
@@ -339,6 +345,7 @@ class TestIPMcast(VppTestCase):
 
         # We expect replications on Pg1 only
         self.verify_capture_ip4(self.pg1, tx)
+        self.assertEqual(route_232.get_stats()['packets'], len(tx))
 
         # no replications on Pg0, Pg2 not Pg3
         self.pg0.assert_nothing_captured(
index d24e4b1..00a79f4 100644 (file)
@@ -362,18 +362,19 @@ class VppIpMRoute(VppObject):
 
     def add_vpp_config(self):
         for path in self.paths:
-            self._test.vapi.ip_mroute_add_del(self.src_addr,
-                                              self.grp_addr,
-                                              self.grp_addr_len,
-                                              self.e_flags,
-                                              path.proto,
-                                              path.nh_itf,
-                                              path.nh_addr,
-                                              path.nh_i_flags,
-                                              bier_imp=path.bier_imp,
-                                              rpf_id=self.rpf_id,
-                                              table_id=self.table_id,
-                                              is_ipv6=self.is_ip6)
+            r = self._test.vapi.ip_mroute_add_del(self.src_addr,
+                                                  self.grp_addr,
+                                                  self.grp_addr_len,
+                                                  self.e_flags,
+                                                  path.proto,
+                                                  path.nh_itf,
+                                                  path.nh_addr,
+                                                  path.nh_i_flags,
+                                                  bier_imp=path.bier_imp,
+                                                  rpf_id=self.rpf_id,
+                                                  table_id=self.table_id,
+                                                  is_ipv6=self.is_ip6)
+            self.stats_index = r.stats_index
         self._test.registry.register(self, self._test.logger)
 
     def remove_vpp_config(self):
@@ -459,6 +460,10 @@ class VppIpMRoute(VppObject):
                        inet_ntop(AF_INET, self.grp_addr),
                        self.grp_addr_len))
 
+    def get_stats(self):
+        c = self._test.statistics.get_counter("/net/mroute")
+        return c[0][self.stats_index]
+
 
 class VppMFibSignal(object):
     def __init__(self, test, route, interface, packet):