summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPat Ruddy <pat@voltanet.io>2020-10-02 13:45:08 +0200
committerPat Ruddy <pat@voltanet.io>2021-02-02 10:37:10 +0100
commit7fd28dd245be1db24283e98bcf0a97d3384bb676 (patch)
tree1bb8e49488f9823b8159889f348a0fa563f17907
parentbgpd: add SNMP mplsL3vpnIfConfTable support (diff)
downloadfrr-7fd28dd245be1db24283e98bcf0a97d3384bb676.tar.xz
frr-7fd28dd245be1db24283e98bcf0a97d3384bb676.zip
bgpd: add mplsL3VpnVrfPerfTable support
support for counts of per-vrf routes: added deleted current Signed-off-by: Pat Ruddy <pat@voltanet.io>
-rw-r--r--bgpd/bgp_mplsvpn_snmp.c107
-rw-r--r--bgpd/bgp_route.c6
-rw-r--r--bgpd/bgpd.h5
3 files changed, 116 insertions, 2 deletions
diff --git a/bgpd/bgp_mplsvpn_snmp.c b/bgpd/bgp_mplsvpn_snmp.c
index 9133a363b..d8e9e2af5 100644
--- a/bgpd/bgp_mplsvpn_snmp.c
+++ b/bgpd/bgp_mplsvpn_snmp.c
@@ -35,6 +35,7 @@
#include "version.h"
#include "bgpd/bgpd.h"
+#include "bgpd/bgp_route.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_mplsvpn_snmp.h"
@@ -74,6 +75,11 @@
#define MPLSL3VPNVRFCONFADMINSTATUS 13
#define MPLSL3VPNVRFCONFSTORAGETYPE 14
+/* MPLSL3VPN PERF Table */
+#define MPLSL3VPNVRFPERFROUTESADDED 1
+#define MPLSL3VPNVRFPERFROUTESDELETED 2
+#define MPLSL3VPNVRFPERFCURRNUMROUTES 3
+
/* SNMP value hack. */
#define INTEGER ASN_INTEGER
#define INTEGER32 ASN_INTEGER
@@ -119,6 +125,9 @@ static uint8_t *mplsL3vpnVrfTable(struct variable *, oid[], size_t *, int,
static uint8_t *mplsL3vpnIfConfTable(struct variable *, oid[], size_t *, int,
size_t *, WriteMethod **);
+static uint8_t *mplsL3vpnPerfTable(struct variable *, oid[], size_t *, int,
+ size_t *, WriteMethod **);
+
static struct variable mpls_l3vpn_variables[] = {
/* BGP version. */
@@ -185,7 +194,7 @@ static struct variable mpls_l3vpn_variables[] = {
5,
{1, 2, 1, 1, 5} },
- /* Vrf Table */
+ /* mplsL3VpnVrf Table */
{MPLSL3VPNVRFVPNID,
OCTET_STRING,
RONLY,
@@ -270,6 +279,26 @@ static struct variable mpls_l3vpn_variables[] = {
mplsL3vpnVrfTable,
5,
{1, 2, 2, 1, 15} },
+
+ /* mplsL3VpnPerfTable */
+ {MPLSL3VPNVRFPERFROUTESADDED,
+ COUNTER32,
+ RONLY,
+ mplsL3vpnPerfTable,
+ 5,
+ {1, 3, 1, 1, 1} },
+ {MPLSL3VPNVRFPERFROUTESDELETED,
+ COUNTER32,
+ RONLY,
+ mplsL3vpnPerfTable,
+ 5,
+ {1, 3, 1, 1, 2} },
+ {MPLSL3VPNVRFPERFCURRNUMROUTES,
+ GAUGE32,
+ RONLY,
+ mplsL3vpnPerfTable,
+ 5,
+ {1, 3, 1, 1, 3} },
};
/* timeticks are in hundredths of a second */
@@ -289,6 +318,28 @@ static int bgp_mpls_l3vpn_update_last_changed(struct bgp *bgp)
return 0;
}
+static uint32_t bgp_mpls_l3vpn_current_routes(struct bgp *l3vpn_bgp)
+{
+ uint32_t count = 0;
+ struct bgp_table *table;
+ struct bgp_dest *dest;
+ struct bgp_path_info *pi;
+
+ table = l3vpn_bgp->rib[AFI_IP][SAFI_UNICAST];
+ for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
+ pi = bgp_dest_get_bgp_path_info(dest);
+ for (; pi; pi = pi->next)
+ count++;
+ }
+ table = l3vpn_bgp->rib[AFI_IP6][SAFI_UNICAST];
+ for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
+ pi = bgp_dest_get_bgp_path_info(dest);
+ for (; pi; pi = pi->next)
+ count++;
+ }
+ return count;
+}
+
static int bgp_init_snmp_stats(struct bgp *bgp)
{
if (is_bgp_vrf_mplsvpn(bgp)) {
@@ -296,9 +347,12 @@ static int bgp_init_snmp_stats(struct bgp *bgp)
bgp->snmp_stats = XCALLOC(
MTYPE_BGP, sizeof(struct bgp_snmp_stats));
/* fix up added routes */
- if (bgp->snmp_stats)
+ if (bgp->snmp_stats) {
+ bgp->snmp_stats->routes_added =
+ bgp_mpls_l3vpn_current_routes(bgp);
bgp_mpls_l3vpn_update_timeticks(
&(bgp->snmp_stats->creation_time));
+ }
}
} else {
if (bgp->snmp_stats) {
@@ -311,6 +365,24 @@ static int bgp_init_snmp_stats(struct bgp *bgp)
return 0;
}
+static int bgp_snmp_update_route_stats(struct bgp_dest *dest,
+ struct bgp_path_info *pi, bool added)
+{
+ struct bgp_table *table;
+
+ if (dest) {
+ table = bgp_dest_table(dest);
+ /* only update if we have a stats block - MPLSVPN vrfs for now*/
+ if (table && table->bgp && table->bgp->snmp_stats) {
+ if (added)
+ table->bgp->snmp_stats->routes_added++;
+ else
+ table->bgp->snmp_stats->routes_deleted++;
+ }
+ }
+ return 0;
+}
+
static bool is_bgp_vrf_active(struct bgp *bgp)
{
struct vrf *vrf;
@@ -705,7 +777,37 @@ static uint8_t *mplsL3vpnVrfTable(struct variable *v, oid name[],
return SNMP_INTEGER(1);
case MPLSL3VPNVRFCONFSTORAGETYPE:
return SNMP_INTEGER(2);
+ }
+ return NULL;
+}
+
+/* 1.3.6.1.2.1.10.166.11.1.3.1.1.x = 14*/
+#define PERFTAB_NAMELEN 14
+
+static uint8_t *mplsL3vpnPerfTable(struct variable *v, oid name[],
+ size_t *length, int exact, size_t *var_len,
+ WriteMethod **write_method)
+{
+ char vrf_name[VRF_NAMSIZ];
+ struct bgp *l3vpn_bgp;
+
+ if (smux_header_table(v, name, length, exact, var_len, write_method)
+ == MATCH_FAILED)
return NULL;
+
+ memset(vrf_name, 0, VRF_NAMSIZ);
+ l3vpn_bgp = bgpL3vpnVrf_lookup(v, name, length, vrf_name, exact);
+
+ if (!l3vpn_bgp)
+ return NULL;
+
+ switch (v->magic) {
+ case MPLSL3VPNVRFPERFROUTESADDED:
+ return SNMP_INTEGER(l3vpn_bgp->snmp_stats->routes_added);
+ case MPLSL3VPNVRFPERFROUTESDELETED:
+ return SNMP_INTEGER(l3vpn_bgp->snmp_stats->routes_deleted);
+ case MPLSL3VPNVRFPERFCURRNUMROUTES:
+ return SNMP_INTEGER(bgp_mpls_l3vpn_current_routes(l3vpn_bgp));
}
return NULL;
}
@@ -716,6 +818,7 @@ void bgp_mpls_l3vpn_module_init(void)
hook_register(bgp_snmp_init_stats, bgp_init_snmp_stats);
hook_register(bgp_snmp_update_last_changed,
bgp_mpls_l3vpn_update_last_changed);
+ hook_register(bgp_snmp_update_stats, bgp_snmp_update_route_stats);
REGISTER_MIB("mplsL3VpnMIB", mpls_l3vpn_variables, variable,
mpls_l3vpn_oid);
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 0ac9a42dc..ce0323b64 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -93,6 +93,10 @@
#include "bgpd/bgp_route_clippy.c"
#endif
+DEFINE_HOOK(bgp_snmp_update_stats,
+ (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
+ (rn, pi, added))
+
/* Extern from bgp_dump.c */
extern const char *bgp_origin_str[];
extern const char *bgp_origin_long_str[];
@@ -402,6 +406,7 @@ void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
bgp_dest_lock_node(dest);
peer_lock(pi->peer); /* bgp_path_info peer reference */
bgp_dest_set_defer_flag(dest, false);
+ hook_call(bgp_snmp_update_stats, dest, pi, true);
}
/* Do the actual removal of info from RIB, for use by bgp_process
@@ -417,6 +422,7 @@ void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
bgp_path_info_mpath_dequeue(pi);
bgp_path_info_unlock(pi);
+ hook_call(bgp_snmp_update_stats, dest, pi, false);
bgp_dest_unlock_node(dest);
}
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 346d904da..9f453bf1e 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -315,6 +315,8 @@ struct bgp_snmp_stats {
time_t creation_time;
time_t modify_time;
bool active;
+ uint32_t routes_added;
+ uint32_t routes_deleted;
};
/* BGP instance structure. */
@@ -2318,6 +2320,9 @@ DECLARE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp),
DECLARE_HOOK(peer_status_changed, (struct peer *peer), (peer))
DECLARE_HOOK(bgp_snmp_init_stats, (struct bgp *bgp), (bgp))
DECLARE_HOOK(bgp_snmp_update_last_changed, (struct bgp *bgp), (bgp))
+DECLARE_HOOK(bgp_snmp_update_stats,
+ (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
+ (rn, pi, added))
void peer_nsf_stop(struct peer *peer);
#endif /* _QUAGGA_BGPD_H */