aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vat/api_format.c8
-rw-r--r--src/vnet/dpo/load_balance.c11
-rw-r--r--src/vnet/fib/fib_entry.c10
-rw-r--r--src/vnet/fib/fib_entry.h2
-rw-r--r--src/vnet/fib/fib_table.c8
-rw-r--r--src/vnet/fib/fib_table.h11
-rw-r--r--src/vnet/ip/ip.api14
-rw-r--r--src/vnet/ip/ip_api.c118
-rw-r--r--src/vnet/mpls/mpls.api9
-rw-r--r--src/vnet/mpls/mpls_api.c68
-rw-r--r--test/test_mpls.py21
-rw-r--r--test/vpp_ip_route.py24
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
@@ -596,6 +596,17 @@ extern void fib_table_entry_delete_index(fib_node_index_t entry_index,
/**
* @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
*
* @param fib_index
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]