zebra: count iface up/down events and keep last time of their occurrence
It is quite useful to be able to assert whether specific interfaces have
flapped or also to verify that specific interfaces have not flapped.
By having counters for those events and storing the last time of their
occurrence, this is made possible.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Tested-by: NetDEF CI System <cisystem@netdef.org>
diff --git a/zebra/interface.c b/zebra/interface.c
index b22186d..14dc589 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -33,6 +33,7 @@
#include "log.h"
#include "zclient.h"
#include "vrf.h"
+#include "command.h"
#include "zebra/interface.h"
#include "zebra/rtadv.h"
@@ -361,6 +362,35 @@
}
}
+static void if_count_up(struct zebra_if *zif)
+{
+ event_counter_inc(&zif->up_events);
+}
+
+static void if_count_down(struct zebra_if *zif)
+{
+ event_counter_inc(&zif->down_events);
+}
+
+void
+if_startup_count_up (void)
+{
+ vrf_iter_t iter;
+ struct interface *ifp;
+ struct zebra_if *zif;
+ struct listnode *node;
+
+ for (iter = vrf_first(); iter != VRF_ITER_INVALID; iter = vrf_next(iter))
+ {
+ for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist(iter), node, ifp))
+ {
+ zif = ifp->info;
+ if (!zif->up_events.count && if_is_operative(ifp))
+ if_count_up(zif);
+ }
+ }
+}
+
/* Handle interface addition */
void
if_add_update (struct interface *ifp)
@@ -402,6 +432,17 @@
zlog_debug ("interface %s vrf %u index %d is added.",
ifp->name, ifp->vrf_id, ifp->ifindex);
}
+
+ if (host_config_get())
+ {
+ /* If configuration and therefore link-detect have already been
+ * loaded, count an initial up event when new interfaces are added
+ * in up state.
+ * If configuration has not been loaded yet, this is handled by
+ * if_startup_count_up which is called after reading the config. */
+ if (!if_data->up_events.count && if_is_operative(ifp))
+ if_count_up(if_data);
+ }
}
/* Handle an interface delete event */
@@ -537,6 +578,8 @@
struct connected *ifc;
struct prefix *p;
+ if_count_up(ifp->info);
+
/* Notify the protocol daemons. */
zebra_interface_up_update (ifp);
@@ -569,6 +612,11 @@
struct listnode *next;
struct connected *ifc;
struct prefix *p;
+ struct zebra_if *zif;
+
+ zif = ifp->info;
+ if (zif->up_events.count)
+ if_count_down(zif);
/* Notify to the protocol daemons. */
zebra_interface_down_update (ifp);
@@ -728,6 +776,11 @@
vty_out (vty, "down%s", VTY_NEWLINE);
}
+ vty_out (vty, " Link ups: %s%s",
+ event_counter_format(&zebra_if->up_events), VTY_NEWLINE);
+ vty_out (vty, " Link downs: %s%s",
+ event_counter_format(&zebra_if->down_events), VTY_NEWLINE);
+
vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
if (ifp->desc)
diff --git a/zebra/interface.h b/zebra/interface.h
index dbb33c5..8baf186 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -23,6 +23,7 @@
#define _ZEBRA_INTERFACE_H
#include "redistribute.h"
+#include "event_counter.h"
#ifdef HAVE_IRDP
#include "zebra/irdp.h"
@@ -188,6 +189,10 @@
/* Installed addresses chains tree. */
struct route_table *ipv4_subnets;
+ /* Information about up/down changes */
+ struct event_counter up_events;
+ struct event_counter down_events;
+
#if defined(HAVE_RTADV)
struct rtadvconf rtadv;
#endif /* RTADV */
@@ -222,6 +227,7 @@
extern void if_down (struct interface *);
extern void if_refresh (struct interface *);
extern void if_flags_update (struct interface *, uint64_t);
+extern void if_startup_count_up (void);
extern int if_subnet_add (struct interface *, struct connected *);
extern int if_subnet_delete (struct interface *, struct connected *);
diff --git a/zebra/main.c b/zebra/main.c
index f3c08f1..8370732 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -440,7 +440,10 @@
/* Don't start execution if we are in dry-run mode */
if (dryrun)
return(0);
-
+
+ /* Count up events for interfaces */
+ if_startup_count_up ();
+
/* Clean up rib. */
rib_weed_tables ();