summaryrefslogtreecommitdiff
path: root/zebra/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/interface.c')
-rw-r--r--zebra/interface.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/zebra/interface.c b/zebra/interface.c
index c30f43456c..a76f8741e0 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);
@@ -206,9 +224,13 @@ static int if_zebra_new_hook(struct interface *ifp)
static void if_nhg_dependents_check_valid(struct nhg_hash_entry *nhe)
{
zebra_nhg_check_valid(nhe);
- if (!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID))
- /* Assuming uninstalled as well here */
- UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
+ if (!CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID)) {
+ /* If we're in shutdown, this interface event needs to clean
+ * up installed NHGs, so don't clear that flag directly.
+ */
+ if (!zrouter.in_shutdown)
+ UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
+ }
}
static void if_down_nhg_dependents(const struct interface *ifp)
@@ -499,7 +521,7 @@ void if_flags_update(struct interface *ifp, uint64_t newflags)
/* inoperative -> operative? */
ifp->flags = newflags;
if (if_is_operative(ifp))
- if_up(ifp);
+ if_up(ifp, true);
}
}
@@ -1027,7 +1049,7 @@ bool if_nhg_dependents_is_empty(const struct interface *ifp)
}
/* Interface is up. */
-void if_up(struct interface *ifp)
+void if_up(struct interface *ifp, bool install_connected)
{
struct zebra_if *zif;
struct interface *link_if;
@@ -1059,7 +1081,8 @@ void if_up(struct interface *ifp)
#endif
/* Install connected routes to the kernel. */
- if_install_connected(ifp);
+ if (install_connected)
+ if_install_connected(ifp);
/* Handle interface up for specific types for EVPN. Non-VxLAN interfaces
* are checked to see if (remote) neighbor entries need to be installed
@@ -2760,7 +2783,7 @@ int if_linkdetect(struct interface *ifp, bool detect)
/* Interface may come up after disabling link detection */
if (if_is_operative(ifp) && !if_was_operative)
- if_up(ifp);
+ if_up(ifp, true);
}
/* FIXME: Will defer status change forwarding if interface
does not come down! */