summaryrefslogtreecommitdiffstats
path: root/zebra/interface.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2022-02-23 16:32:23 +0100
committerDonald Sharp <sharpd@nvidia.com>2022-02-28 12:39:07 +0100
commitfbc83b9a106bd795aa554255f674edee6ec66526 (patch)
tree9e4fb4b3c2e74fa5d150985f5bfa889686cec245 /zebra/interface.c
parenttools: Add `show thread timers` to support bundle generation (diff)
downloadfrr-fbc83b9a106bd795aa554255f674edee6ec66526.tar.xz
frr-fbc83b9a106bd795aa554255f674edee6ec66526.zip
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 <sharpd@nvidia.com>
Diffstat (limited to 'zebra/interface.c')
-rw-r--r--zebra/interface.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/zebra/interface.c b/zebra/interface.c
index c30f43456..fbd2aac00 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);