]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: add mplsL3VpnVrfPerfTable support
authorPat Ruddy <pat@voltanet.io>
Fri, 2 Oct 2020 11:45:08 +0000 (12:45 +0100)
committerPat Ruddy <pat@voltanet.io>
Tue, 2 Feb 2021 09:37:10 +0000 (09:37 +0000)
support for counts of per-vrf routes:
added
deleted
current

Signed-off-by: Pat Ruddy <pat@voltanet.io>
bgpd/bgp_mplsvpn_snmp.c
bgpd/bgp_route.c
bgpd/bgpd.h

index 9133a363b7d625c0b49ed53326a9c77b9688ed53..d8e9e2af5e98888c4aadee94016d0fdca4fca91c 100644 (file)
@@ -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"
 
 #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);
 }
index 0ac9a42dc5172b9493aaeb7bb14b89330f532d5f..ce0323b646b10b234219e2cbe9f7cfe7d190e6a3 100644 (file)
 #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);
 }
 
index 346d904da5aacc775fd62f2032b82689c21cdf61..9f453bf1e63c8256faa12617c7025266c2ebc2b6 100644 (file)
@@ -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 */