]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Limit speed lookup to at most 4 minutes
authorDonald Sharp <sharpd@nvidia.com>
Wed, 23 Feb 2022 15:32:23 +0000 (10:32 -0500)
committerDonald Sharp <sharpd@nvidia.com>
Mon, 28 Feb 2022 11:39:07 +0000 (06:39 -0500)
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>
zebra/interface.c
zebra/interface.h

index c30f43456cfae6e1295bc1213c39f062affd17b6..fbd2aac005843207267306171b45f85f6f15f120 100644 (file)
@@ -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);
index 85617961af990fd1daba1908ac9f0ce7d1afaad9..c19e494860cb2eefca90703e577bdb913dac9ea0 100644 (file)
@@ -412,6 +412,7 @@ struct zebra_if {
        ifindex_t link_ifindex;
        struct interface *link;
 
+       uint8_t speed_update_count;
        struct thread *speed_update;
 
        /*