From: Christian Franke <[email protected]> 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 <[email protected]> --- zebra/interface.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ zebra/interface.h | 6 ++++++ zebra/main.c | 5 ++++- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/zebra/interface.c b/zebra/interface.c index 8a9225a..f4cd5f6 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 @@ if_addr_wakeup (struct interface *ifp) } } +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 @@ if_add_update (struct interface *ifp) 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 @@ if_up (struct interface *ifp) struct connected *ifc; struct prefix *p; + if_count_up(ifp->info); + /* Notify the protocol daemons. */ zebra_interface_up_update (ifp); @@ -569,6 +612,11 @@ if_down (struct interface *ifp) 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 @@ if_dump_vty (struct vty *vty, struct interface *ifp) 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 @@ struct zebra_if /* 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_up (struct interface *); 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 @@ main (int argc, char **argv) /* 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 (); -- 2.8.0 _______________________________________________ Quagga-dev mailing list [email protected] https://lists.quagga.net/mailman/listinfo/quagga-dev
