From fbc83b9a106bd795aa554255f674edee6ec66526 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 23 Feb 2022 10:32:23 -0500 Subject: [PATCH] zebra: Limit speed lookup to at most 4 minutes There exists some interface types that are slow on startup to fully register their link speed. Especially those that are working with an asic backend. The speed_update timer associated with each interface would keep trying if the system returned a MAX_UINT32 as the speed. This speed means both unknown or there is none under linux. Since some interface types are slow on startup let's modify FRR to try for at most 4 minutes and give up trying on those interfaces where we never get any useful data. Why 4 minutes? I wanted to balance the time associated with slow interfaces coming up with those that will never give us a value. So I choose 4 minutes as a good ballpark of time to keep trying Why not track all those interfaces and just not attempt to do the speed lookup? I would prefer to not keep track of these as that I do not know all the interface types, nor do I wish to keep programming as new ones come in. Signed-off-by: Donald Sharp --- zebra/interface.c | 26 ++++++++++++++++++++++---- zebra/interface.h | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/zebra/interface.c b/zebra/interface.c index c30f43456c..fbd2aac005 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -72,8 +72,6 @@ static void if_zebra_speed_update(struct thread *thread) bool changed = false; int error = 0; - zif->speed_update = NULL; - new_speed = kernel_get_speed(ifp, &error); /* error may indicate vrf not available or @@ -92,8 +90,27 @@ static void if_zebra_speed_update(struct thread *thread) } if (changed || new_speed == UINT32_MAX) { - thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 5, - &zif->speed_update); +#define SPEED_UPDATE_SLEEP_TIME 5 +#define SPEED_UPDATE_COUNT_MAX (4 * 60 / SPEED_UPDATE_SLEEP_TIME) + /* + * Some interfaces never actually have an associated speed + * with them ( I am looking at you bridges ). + * So instead of iterating forever, let's give the + * system 4 minutes to try to figure out the speed + * if after that it it's probably never going to become + * useful. + * Since I don't know all the wonderful types of interfaces + * that may come into existence in the future I am going + * to not update the system to keep track of that. This + * is far simpler to just stop trying after 4 minutes + */ + if (new_speed == UINT32_MAX && + zif->speed_update_count == SPEED_UPDATE_COUNT_MAX) + return; + + zif->speed_update_count++; + thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, + SPEED_UPDATE_SLEEP_TIME, &zif->speed_update); thread_ignore_late_timer(zif->speed_update); } } @@ -196,6 +213,7 @@ static int if_zebra_new_hook(struct interface *ifp) * of seconds and ask again. Hopefully it's all settled * down upon startup. */ + zebra_if->speed_update_count = 0; thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15, &zebra_if->speed_update); thread_ignore_late_timer(zebra_if->speed_update); diff --git a/zebra/interface.h b/zebra/interface.h index 85617961af..c19e494860 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -412,6 +412,7 @@ struct zebra_if { ifindex_t link_ifindex; struct interface *link; + uint8_t speed_update_count; struct thread *speed_update; /* -- 2.39.5