Route counters in the stats segment 97/14897/3
authorNeale Ranns <nranns@cisco.com>
Fri, 7 Sep 2018 16:32:36 +0000 (09:32 -0700)
committerDamjan Marion <dmarion@me.com>
Thu, 20 Sep 2018 10:05:11 +0000 (10:05 +0000)
route ADD API changed to return the stats segment index to use to read the counters

Change-Id: I2ef41e01eaa2f9cfaa49d9c88968897793825925
Signed-off-by: Neale Ranns <nranns@cisco.com>
12 files changed:
src/vat/api_format.c
src/vnet/dpo/load_balance.c
src/vnet/fib/fib_entry.c
src/vnet/fib/fib_entry.h
src/vnet/fib/fib_table.c
src/vnet/fib/fib_table.h
src/vnet/ip/ip.api
src/vnet/ip/ip_api.c
src/vnet/mpls/mpls.api
src/vnet/mpls/mpls_api.c
test/test_mpls.py
test/vpp_ip_route.py

index 5e1114f..61b3497 100644 (file)
@@ -20440,9 +20440,9 @@ vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
   int i;
 
   print (vam->ofp,
-        "table-id %d, prefix %U/%d",
+        "table-id %d, prefix %U/%d stats-index %d",
         ntohl (mp->table_id), format_ip4_address, mp->address,
-        mp->address_length);
+        mp->address_length, ntohl (mp->stats_index));
   fp = mp->path;
   for (i = 0; i < count; i++)
     {
@@ -20652,9 +20652,9 @@ vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
   int i;
 
   print (vam->ofp,
-        "table-id %d, prefix %U/%d",
+        "table-id %d, prefix %U/%d stats-index %d",
         ntohl (mp->table_id), format_ip6_address, mp->address,
-        mp->address_length);
+        mp->address_length, ntohl (mp->stats_index));
   fp = mp->path;
   for (i = 0; i < count; i++)
     {
index ae95b6e..37f8ca1 100644 (file)
@@ -53,7 +53,16 @@ load_balance_t *load_balance_pool;
 /**
  * The one instance of load-balance main
  */
-load_balance_main_t load_balance_main;
+load_balance_main_t load_balance_main = {
+    .lbm_to_counters = {
+        .name = "route-to",
+        .stat_segment_name = "/net/route/to",
+    },
+    .lbm_via_counters = {
+        .name = "route-via",
+        .stat_segment_name = "/net/route/via",
+    }
+};
 
 f64
 load_balance_get_multipath_tolerance (void)
index 6555265..8d7ce00 100644 (file)
@@ -1495,6 +1495,16 @@ fib_entry_set_flow_hash_config (fib_node_index_t fib_entry_index,
     }
 }
 
+u32
+fib_entry_get_stats_index (fib_node_index_t fib_entry_index)
+{
+    fib_entry_t *fib_entry;
+
+    fib_entry = fib_entry_get(fib_entry_index);
+
+    return (fib_entry->fe_lb.dpoi_index);
+}
+
 static int
 fib_ip4_address_compare (const ip4_address_t * a1,
                          const ip4_address_t * a2)
index 61b8149..9175a57 100644 (file)
@@ -623,6 +623,8 @@ extern void fib_entry_set_flow_hash_config(fib_node_index_t fib_entry_index,
 
 extern void fib_entry_module_init(void);
 
+extern u32 fib_entry_get_stats_index(fib_node_index_t fib_entry_index);
+
 /*
  * unsafe... beware the raw pointer.
  */
index f63edaa..d8e8d63 100644 (file)
@@ -885,6 +885,14 @@ fib_table_entry_delete_index (fib_node_index_t fib_entry_index,
                              fib_entry_index, prefix, source);
 }
 
+u32
+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)));
+}
+
 fib_node_index_t
 fib_table_entry_local_label_add (u32 fib_index,
                                 const fib_prefix_t *prefix,
index 8b86f8d..f13dd77 100644 (file)
@@ -594,6 +594,17 @@ extern void fib_table_entry_delete(u32 fib_index,
 extern void fib_table_entry_delete_index(fib_node_index_t entry_index,
                                         fib_source_t source);
 
+/**
+ * @brief
+ *  Return the stats index for a FIB entry
+ * @param fib_index
+ *  The table's FIB index
+ * @param prefix
+ *  The entry's prefix's
+ */
+extern u32 fib_table_entry_get_stats_index(u32 fib_index,
+                                           const fib_prefix_t *prefix);
+
 /**
  * @brief
  *  Flush all entries from a table for the source
index 616d621..7c7f656 100644 (file)
@@ -1,5 +1,6 @@
+/* Hey Emacs use -*- mode: C -*- */
 /*
- * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Copyright (c) 2018 Cisco and/or its affiliates.
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
@@ -70,6 +71,7 @@ manual_endian manual_print define ip_fib_details
   u8  address_length;
   u8  address[4];
   u32 count;
+  u32 stats_index;
   vl_api_fib_path_t path[count];
 };
 
@@ -97,6 +99,7 @@ manual_endian manual_print define ip6_fib_details
   u8  address_length;
   u8  address[16];
   u32 count;
+  u32 stats_index;
   vl_api_fib_path_t path[count];
 };
 
@@ -389,7 +392,7 @@ autoreply define sw_interface_ip6_set_link_local_address
     @param next_hop_out_label_stack - the next-hop output label stack, outer most first
     @param next_hop_via_label - The next-hop is a resolved via a local label
 */
-autoreply define ip_add_del_route
+define ip_add_del_route
 {
   u32 client_index;
   u32 context;
@@ -422,6 +425,13 @@ autoreply define ip_add_del_route
   vl_api_fib_mpls_label_t next_hop_out_label_stack[next_hop_n_out_labels];
 };
 
+define ip_add_del_route_reply
+{
+  u32 context;
+  i32 retval;
+  u32 stats_index;
+};
+
 /** \brief Add / del route request
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
index 431a777..bed5889 100644 (file)
@@ -212,6 +212,8 @@ send_ip_fib_details (vpe_api_main_t * am,
          clib_min (vec_len (table->ft_desc), sizeof (mp->table_name)));
   mp->address_length = pfx->fp_len;
   memcpy (mp->address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
+  mp->stats_index =
+    htonl (fib_table_entry_get_stats_index (table->ft_index, pfx));
 
   mp->count = htonl (path_count);
   fp = mp->path;
@@ -309,6 +311,8 @@ send_ip6_fib_details (vpe_api_main_t * am,
   memcpy (mp->address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
   memcpy (mp->table_name, table->ft_desc,
          clib_min (vec_len (table->ft_desc), sizeof (mp->table_name)));
+  mp->stats_index =
+    htonl (fib_table_entry_get_stats_index (table->ft_index, pfx));
 
   mp->count = htonl (path_count);
   fp = mp->path;
@@ -962,7 +966,8 @@ add_del_route_check (fib_protocol_t table_proto,
 }
 
 static int
-ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
+                            u32 * stats_index)
 {
   u32 fib_index, next_hop_fib_index;
   fib_mpls_label_t *label_stack = NULL;
@@ -1006,32 +1011,37 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
        }
     }
 
-  return (add_del_route_t_handler (mp->is_multipath,
-                                  mp->is_add,
-                                  mp->is_drop,
-                                  mp->is_unreach,
-                                  mp->is_prohibit,
-                                  mp->is_local, 0,
-                                  mp->is_classify,
-                                  mp->classify_table_index,
-                                  mp->is_resolve_host,
-                                  mp->is_resolve_attached, 0, 0,
-                                  mp->is_dvr,
-                                  mp->is_source_lookup,
-                                  mp->is_udp_encap,
-                                  fib_index, &pfx, DPO_PROTO_IP4,
-                                  &nh,
-                                  ntohl (mp->next_hop_id),
-                                  ntohl (mp->next_hop_sw_if_index),
-                                  next_hop_fib_index,
-                                  mp->next_hop_weight,
-                                  mp->next_hop_preference,
-                                  ntohl (mp->next_hop_via_label),
-                                  label_stack));
+  rv = add_del_route_t_handler (mp->is_multipath,
+                               mp->is_add,
+                               mp->is_drop,
+                               mp->is_unreach,
+                               mp->is_prohibit,
+                               mp->is_local, 0,
+                               mp->is_classify,
+                               mp->classify_table_index,
+                               mp->is_resolve_host,
+                               mp->is_resolve_attached, 0, 0,
+                               mp->is_dvr,
+                               mp->is_source_lookup,
+                               mp->is_udp_encap,
+                               fib_index, &pfx, DPO_PROTO_IP4,
+                               &nh,
+                               ntohl (mp->next_hop_id),
+                               ntohl (mp->next_hop_sw_if_index),
+                               next_hop_fib_index,
+                               mp->next_hop_weight,
+                               mp->next_hop_preference,
+                               ntohl (mp->next_hop_via_label), label_stack);
+
+  if (mp->is_add && 0 == rv)
+    *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);
+
+  return (rv);
 }
 
 static int
-ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp,
+                            u32 * stats_index)
 {
   fib_mpls_label_t *label_stack = NULL;
   u32 fib_index, next_hop_fib_index;
@@ -1075,46 +1085,57 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
        }
     }
 
-  return (add_del_route_t_handler (mp->is_multipath,
-                                  mp->is_add,
-                                  mp->is_drop,
-                                  mp->is_unreach,
-                                  mp->is_prohibit,
-                                  mp->is_local, 0,
-                                  mp->is_classify,
-                                  mp->classify_table_index,
-                                  mp->is_resolve_host,
-                                  mp->is_resolve_attached, 0, 0,
-                                  mp->is_dvr,
-                                  mp->is_source_lookup,
-                                  mp->is_udp_encap,
-                                  fib_index, &pfx, DPO_PROTO_IP6,
-                                  &nh, ntohl (mp->next_hop_id),
-                                  ntohl (mp->next_hop_sw_if_index),
-                                  next_hop_fib_index,
-                                  mp->next_hop_weight,
-                                  mp->next_hop_preference,
-                                  ntohl (mp->next_hop_via_label),
-                                  label_stack));
+  rv = add_del_route_t_handler (mp->is_multipath,
+                               mp->is_add,
+                               mp->is_drop,
+                               mp->is_unreach,
+                               mp->is_prohibit,
+                               mp->is_local, 0,
+                               mp->is_classify,
+                               mp->classify_table_index,
+                               mp->is_resolve_host,
+                               mp->is_resolve_attached, 0, 0,
+                               mp->is_dvr,
+                               mp->is_source_lookup,
+                               mp->is_udp_encap,
+                               fib_index, &pfx, DPO_PROTO_IP6,
+                               &nh, ntohl (mp->next_hop_id),
+                               ntohl (mp->next_hop_sw_if_index),
+                               next_hop_fib_index,
+                               mp->next_hop_weight,
+                               mp->next_hop_preference,
+                               ntohl (mp->next_hop_via_label), label_stack);
+
+  if (mp->is_add && 0 == rv)
+    *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);
+
+  return (rv);
 }
 
 void
 vl_api_ip_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
 {
   vl_api_ip_add_del_route_reply_t *rmp;
+  u32 stats_index;
   int rv;
   vnet_main_t *vnm = vnet_get_main ();
 
   vnm->api_errno = 0;
+  stats_index = ~0;
 
   if (mp->is_ipv6)
-    rv = ip6_add_del_route_t_handler (mp);
+    rv = ip6_add_del_route_t_handler (mp, &stats_index);
   else
-    rv = ip4_add_del_route_t_handler (mp);
+    rv = ip4_add_del_route_t_handler (mp, &stats_index);
 
   rv = (rv == 0) ? vnm->api_errno : rv;
 
-  REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY);
+  /* *INDENT-OFF* */
+  REPLY_MACRO2 (VL_API_IP_ADD_DEL_ROUTE_REPLY,
+  ({
+    rmp->stats_index = htonl (stats_index);
+  }))
+  /* *INDENT-ON* */
 }
 
 void
@@ -1401,6 +1422,7 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
       }));
       /* *INDENT-ON* */
     }
+
   BAD_SW_IF_INDEX_LABEL;
 }
 
index 7ab0f37..7fa24f4 100644 (file)
@@ -142,7 +142,7 @@ autoreply define mpls_table_add_del
     @param mr_next_hop_out_label_stack - the next-hop output label stack, outer most first
     @param next_hop_via_label - The next-hop is a resolved via a local label
 */
-autoreply define mpls_route_add_del
+define mpls_route_add_del
 {
   u32 client_index;
   u32 context;
@@ -169,6 +169,13 @@ autoreply define mpls_route_add_del
   vl_api_fib_mpls_label_t mr_next_hop_out_label_stack[mr_next_hop_n_out_labels];
 };
 
+define mpls_route_add_del_reply
+{
+  u32 context;
+  i32 retval;
+  u32 stats_index;
+};
+
 /** \brief Dump MPLS fib table
     @param client_index - opaque cookie to identify the sender
 */
index 8fec8e8..dbd1d8b 100644 (file)
@@ -168,7 +168,8 @@ vl_api_mpls_ip_bind_unbind_t_handler (vl_api_mpls_ip_bind_unbind_t * mp)
 
 static int
 mpls_route_add_del_t_handler (vnet_main_t * vnm,
-                             vl_api_mpls_route_add_del_t * mp)
+                             vl_api_mpls_route_add_del_t * mp,
+                             u32 * stats_index)
 {
   fib_mpls_label_t *label_stack = NULL;
   u32 fib_index, next_hop_fib_index;
@@ -227,31 +228,36 @@ mpls_route_add_del_t_handler (vnet_main_t * vnm,
     }
 
   /* *INDENT-OFF* */
-  return (add_del_route_t_handler (mp->mr_is_multipath, mp->mr_is_add,
-                                   0,  // mp->is_drop,
-                                  0,   // mp->is_unreach,
-                                  0,   // mp->is_prohibit,
-                                  0,   // mp->is_local,
-                                  mp->mr_is_multicast,
-                                   mp->mr_is_classify,
-                                   mp->mr_classify_table_index,
-                                   mp->mr_is_resolve_host,
-                                   mp->mr_is_resolve_attached,
-                                   mp->mr_is_interface_rx,
-                                   mp->mr_is_rpf_id,
-                                   0,  // l2_bridged
-                                   0,   // is source_lookup
-                                   0,   // is_udp_encap
+  rv = add_del_route_t_handler (mp->mr_is_multipath, mp->mr_is_add,
+                                0,     // mp->is_drop,
+                                0,     // mp->is_unreach,
+                                0,     // mp->is_prohibit,
+                                0,     // mp->is_local,
+                                mp->mr_is_multicast,
+                                mp->mr_is_classify,
+                                mp->mr_classify_table_index,
+                                mp->mr_is_resolve_host,
+                                mp->mr_is_resolve_attached,
+                                mp->mr_is_interface_rx,
+                                mp->mr_is_rpf_id,
+                                0,     // l2_bridged
+                                0,   // is source_lookup
+                                0,   // is_udp_encap
                                   fib_index, &pfx,
-                                  mp->mr_next_hop_proto,
-                                  &nh, ~0, // next_hop_id
-                                   ntohl (mp->mr_next_hop_sw_if_index),
-                                  next_hop_fib_index,
-                                  mp->mr_next_hop_weight,
-                                  mp->mr_next_hop_preference,
-                                  ntohl (mp->mr_next_hop_via_label),
-                                  label_stack));
+                                mp->mr_next_hop_proto,
+                                &nh, ~0, // next_hop_id
+                                ntohl (mp->mr_next_hop_sw_if_index),
+                                next_hop_fib_index,
+                                mp->mr_next_hop_weight,
+                                mp->mr_next_hop_preference,
+                                ntohl (mp->mr_next_hop_via_label),
+                                label_stack);
   /* *INDENT-ON* */
+
+  if (mp->mr_is_add && 0 == rv)
+    *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);
+
+  return (rv);
 }
 
 void
@@ -259,16 +265,20 @@ vl_api_mpls_route_add_del_t_handler (vl_api_mpls_route_add_del_t * mp)
 {
   vl_api_mpls_route_add_del_reply_t *rmp;
   vnet_main_t *vnm;
+  u32 stats_index;
   int rv;
 
   vnm = vnet_get_main ();
-  vnm->api_errno = 0;
+  stats_index = ~0;
 
-  rv = mpls_route_add_del_t_handler (vnm, mp);
-
-  rv = (rv == 0) ? vnm->api_errno : rv;
+  rv = mpls_route_add_del_t_handler (vnm, mp, &stats_index);
 
-  REPLY_MACRO (VL_API_MPLS_ROUTE_ADD_DEL_REPLY);
+  /* *INDENT-OFF* */
+  REPLY_MACRO2 (VL_API_MPLS_ROUTE_ADD_DEL_REPLY,
+  ({
+    rmp->stats_index = htonl (stats_index);
+  }));
+  /* *INDENT-ON* */
 }
 
 void
index d943f82..1a4dad1 100644 (file)
@@ -389,6 +389,8 @@ class TestMPLS(VppTestCase):
         self.verify_capture_labelled(self.pg0, rx, tx,
                                      [VppMplsLabel(33, ttl=31, exp=1)])
 
+        self.assertEqual(route_32_eos.get_stats_to()['packets'], 257)
+
         #
         # A simple MPLS xconnect - non-eos label in label out
         #
@@ -409,6 +411,7 @@ class TestMPLS(VppTestCase):
         self.verify_capture_labelled(self.pg0, rx, tx,
                                      [VppMplsLabel(33, ttl=20, exp=7),
                                       VppMplsLabel(99)])
+        self.assertEqual(route_32_neos.get_stats_to()['packets'], 257)
 
         #
         # A simple MPLS xconnect - non-eos label in label out, uniform mode
@@ -575,6 +578,9 @@ class TestMPLS(VppTestCase):
                                       VppMplsLabel(44),
                                       VppMplsLabel(45, ttl=2)])
 
+        self.assertEqual(route_34_eos.get_stats_to()['packets'], 257)
+        self.assertEqual(route_32_neos.get_stats_via()['packets'], 257)
+
         #
         # A recursive EOS x-connect, which resolves through another x-connect
         # in uniform mode
@@ -635,6 +641,7 @@ class TestMPLS(VppTestCase):
                                           VppMplsLabel(44),
                                           VppMplsLabel(46),
                                           VppMplsLabel(55)])
+        self.assertEqual(ip_10_0_0_1.get_stats_to()['packets'], 257)
 
         ip_10_0_0_1.remove_vpp_config()
         route_34_neos.remove_vpp_config()
@@ -782,6 +789,8 @@ class TestMPLS(VppTestCase):
                                          [VppMplsLabel(32),
                                           VppMplsLabel(44)])
 
+        self.assertEqual(route_11_0_0_1.get_stats_to()['packets'], 257)
+
         #
         # add a recursive path, with 2 labels, via the 3 label route
         #
@@ -805,6 +814,18 @@ class TestMPLS(VppTestCase):
                                           VppMplsLabel(44),
                                           VppMplsLabel(45)])
 
+        self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 257)
+
+        rx = self.send_and_expect(self.pg0, tx, self.pg0)
+        self.verify_capture_labelled_ip4(self.pg0, rx, tx,
+                                         [VppMplsLabel(32),
+                                          VppMplsLabel(33),
+                                          VppMplsLabel(34),
+                                          VppMplsLabel(44),
+                                          VppMplsLabel(45)])
+
+        self.assertEqual(route_11_0_0_2.get_stats_to()['packets'], 514)
+
         #
         # cleanup
         #
index 18c27ff..d24e4b1 100644 (file)
@@ -244,7 +244,7 @@ class VppIpRoute(VppObject):
     def add_vpp_config(self):
         if self.is_local or self.is_unreach or \
            self.is_prohibit or self.is_drop:
-            self._test.vapi.ip_add_del_route(
+            r = self._test.vapi.ip_add_del_route(
                 self.dest_addr,
                 self.dest_addr_len,
                 inet_pton(AF_INET6, "::"),
@@ -259,7 +259,7 @@ class VppIpRoute(VppObject):
             for path in self.paths:
                 lstack = path.encode_labels()
 
-                self._test.vapi.ip_add_del_route(
+                r = self._test.vapi.ip_add_del_route(
                     self.dest_addr,
                     self.dest_addr_len,
                     path.nh_addr,
@@ -277,6 +277,7 @@ class VppIpRoute(VppObject):
                     is_source_lookup=path.is_source_lookup,
                     is_udp_encap=path.is_udp_encap,
                     is_multipath=1 if len(self.paths) > 1 else 0)
+        self.stats_index = r.stats_index
         self._test.registry.register(self, self._test.logger)
 
     def remove_vpp_config(self):
@@ -325,6 +326,14 @@ class VppIpRoute(VppObject):
                    self.dest_addr_p,
                    self.dest_addr_len))
 
+    def get_stats_to(self):
+        c = self._test.statistics.get_counter("/net/route/to")
+        return c[0][self.stats_index]
+
+    def get_stats_via(self):
+        c = self._test.statistics.get_counter("/net/route/via")
+        return c[0][self.stats_index]
+
 
 class VppIpMRoute(VppObject):
     """
@@ -581,7 +590,7 @@ class VppMplsRoute(VppObject):
         for path in self.paths:
             lstack = path.encode_labels()
 
-            self._test.vapi.mpls_route_add_del(
+            r = self._test.vapi.mpls_route_add_del(
                 self.local_label,
                 self.eos_bit,
                 path.proto,
@@ -596,6 +605,7 @@ class VppMplsRoute(VppObject):
                 next_hop_n_out_labels=len(lstack),
                 next_hop_via_label=path.nh_via_label,
                 next_hop_table_id=path.nh_table_id)
+        self.stats_index = r.stats_index
         self._test.registry.register(self, self._test.logger)
 
     def remove_vpp_config(self):
@@ -626,3 +636,11 @@ class VppMplsRoute(VppObject):
                 % (self.table_id,
                    self.local_label,
                    20+self.eos_bit))
+
+    def get_stats_to(self):
+        c = self._test.statistics.get_counter("/net/route/to")
+        return c[0][self.stats_index]
+
+    def get_stats_via(self):
+        c = self._test.statistics.get_counter("/net/route/via")
+        return c[0][self.stats_index]