From 7fd28dd245be1db24283e98bcf0a97d3384bb676 Mon Sep 17 00:00:00 2001 From: Pat Ruddy Date: Fri, 2 Oct 2020 12:45:08 +0100 Subject: bgpd: add mplsL3VpnVrfPerfTable support support for counts of per-vrf routes: added deleted current Signed-off-by: Pat Ruddy --- bgpd/bgp_mplsvpn_snmp.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++- bgpd/bgp_route.c | 6 +++ bgpd/bgpd.h | 5 +++ 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 */ -- cgit v1.2.3