From 008dbe109ce2714be69ffb6549a0c0198a07f7d0 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Fri, 7 Sep 2018 09:32:36 -0700 Subject: [PATCH] Route counters in the stats segment route ADD API changed to return the stats segment index to use to read the counters Change-Id: I2ef41e01eaa2f9cfaa49d9c88968897793825925 Signed-off-by: Neale Ranns --- src/vat/api_format.c | 8 +-- src/vnet/dpo/load_balance.c | 11 ++++- src/vnet/fib/fib_entry.c | 10 ++++ src/vnet/fib/fib_entry.h | 2 + src/vnet/fib/fib_table.c | 8 +++ src/vnet/fib/fib_table.h | 11 +++++ src/vnet/ip/ip.api | 14 +++++- src/vnet/ip/ip_api.c | 118 ++++++++++++++++++++++++++------------------ src/vnet/mpls/mpls.api | 9 +++- src/vnet/mpls/mpls_api.c | 68 ++++++++++++++----------- test/test_mpls.py | 21 ++++++++ test/vpp_ip_route.py | 24 +++++++-- 12 files changed, 216 insertions(+), 88 deletions(-) diff --git a/src/vat/api_format.c b/src/vat/api_format.c index 5e1114fdfbd..61b34973d6f 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -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++) { diff --git a/src/vnet/dpo/load_balance.c b/src/vnet/dpo/load_balance.c index ae95b6e1b3e..37f8ca1d89d 100644 --- a/src/vnet/dpo/load_balance.c +++ b/src/vnet/dpo/load_balance.c @@ -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) diff --git a/src/vnet/fib/fib_entry.c b/src/vnet/fib/fib_entry.c index 655526586cb..8d7ce00b9c0 100644 --- a/src/vnet/fib/fib_entry.c +++ b/src/vnet/fib/fib_entry.c @@ -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) diff --git a/src/vnet/fib/fib_entry.h b/src/vnet/fib/fib_entry.h index 61b81493756..9175a571032 100644 --- a/src/vnet/fib/fib_entry.h +++ b/src/vnet/fib/fib_entry.h @@ -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. */ diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c index f63edaa76f0..d8e8d63b9ae 100644 --- a/src/vnet/fib/fib_table.c +++ b/src/vnet/fib/fib_table.c @@ -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, diff --git a/src/vnet/fib/fib_table.h b/src/vnet/fib/fib_table.h index 8b86f8d6dd9..f13dd77c8b4 100644 --- a/src/vnet/fib/fib_table.h +++ b/src/vnet/fib/fib_table.h @@ -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 diff --git a/src/vnet/ip/ip.api b/src/vnet/ip/ip.api index 616d621577d..7c7f656d2e6 100644 --- a/src/vnet/ip/ip.api +++ b/src/vnet/ip/ip.api @@ -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 diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index 431a777442f..bed5889b24a 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -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; } diff --git a/src/vnet/mpls/mpls.api b/src/vnet/mpls/mpls.api index 7ab0f3750cc..7fa24f4812d 100644 --- a/src/vnet/mpls/mpls.api +++ b/src/vnet/mpls/mpls.api @@ -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 */ diff --git a/src/vnet/mpls/mpls_api.c b/src/vnet/mpls/mpls_api.c index 8fec8e82e1e..dbd1d8b6e31 100644 --- a/src/vnet/mpls/mpls_api.c +++ b/src/vnet/mpls/mpls_api.c @@ -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 diff --git a/test/test_mpls.py b/test/test_mpls.py index d943f8281e9..1a4dad18e30 100644 --- a/test/test_mpls.py +++ b/test/test_mpls.py @@ -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 # diff --git a/test/vpp_ip_route.py b/test/vpp_ip_route.py index 18c27ffa942..d24e4b1e487 100644 --- a/test/vpp_ip_route.py +++ b/test/vpp_ip_route.py @@ -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] -- 2.16.6