summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_lsa.c
diff options
context:
space:
mode:
authorJoakim Tjernlund <Joakim.Tjernlund@transmode.se>2009-07-27 12:42:35 +0200
committerPaul Jakma <paul@quagga.net>2009-08-11 18:33:27 +0200
commit5996e0df2eb325445114517209cd24f37d91774a (patch)
tree56bee1d2ab48d4b7a5e163747b54d7537f4df9a3 /ospfd/ospf_lsa.c
parentospfd: Make "Packet ... received on wrong link" conditional on debug (diff)
downloadfrr-5996e0df2eb325445114517209cd24f37d91774a.tar.xz
frr-5996e0df2eb325445114517209cd24f37d91774a.zip
ospfd: Make sure route table is recalculated.
In some cases ospfd does not recalc the route table. This happens when ospfd receives an old LSA which will trigger recalc but the this recalc will fail because all interfaces isn't up yet. Next LSA that is originated matches the old one so no recalc will be performed. This problem has been observed when there are only 2 ppp I/Fs in an area, both go down at the same time, then they come up again with a few seconds apart. * ospf_lsa.c: (ospf_{router,network}_lsa_install) avoid a needless scheduling of SPF. (ospf_lsa_different) fix bug in LSA comparison that would lead to the described failure to schedule SPF.
Diffstat (limited to 'ospfd/ospf_lsa.c')
-rw-r--r--ospfd/ospf_lsa.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 22612f6f5..9e80664b9 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -2414,28 +2414,28 @@ ospf_router_lsa_install (struct ospf *ospf,
the shortest path calculations for each area (not just the
area whose link-state database has changed).
*/
- if (rt_recalc)
- ospf_spf_calculate_schedule (ospf);
- /* Only install LSA if it is originated/refreshed by us.
- * If LSA was received by flooding, the RECEIVED flag is set so do
- * not link the LSA */
- if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
+ if (IS_LSA_SELF (new))
{
+
+ /* Only install LSA if it is originated/refreshed by us.
+ * If LSA was received by flooding, the RECEIVED flag is set so do
+ * not link the LSA */
+ if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
+ return new; /* ignore stale LSA */
+
/* Set router-LSA refresh timer. */
OSPF_TIMER_OFF (area->t_router_lsa_self);
OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
-
+
/* Set self-originated router-LSA. */
ospf_lsa_unlock (&area->router_lsa_self);
area->router_lsa_self = ospf_lsa_lock (new);
- if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
- zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
- new->data->type, inet_ntoa (new->data->id),
- ntohl(new->data->ls_seqnum));
}
+ if (rt_recalc)
+ ospf_spf_calculate_schedule (ospf);
return new;
}
@@ -2457,14 +2457,14 @@ ospf_network_lsa_install (struct ospf *ospf,
the shortest path calculations for each area (not just the
area whose link-state database has changed).
*/
- if (rt_recalc)
- ospf_spf_calculate_schedule (ospf);
-
- /* We supposed that when LSA is originated by us, we pass the int
- for which it was originated. If LSA was received by flooding,
- the RECEIVED flag is set, so we do not link the LSA to the int. */
- if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
+ if (IS_LSA_SELF (new))
{
+ /* We supposed that when LSA is originated by us, we pass the int
+ for which it was originated. If LSA was received by flooding,
+ the RECEIVED flag is set, so we do not link the LSA to the int. */
+ if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
+ return new; /* ignore stale LSA */
+
/* Set LSRefresh timer. */
OSPF_TIMER_OFF (oi->t_network_lsa_self);
@@ -2475,6 +2475,8 @@ ospf_network_lsa_install (struct ospf *ospf,
ospf_lsa_unlock (&oi->network_lsa_self);
oi->network_lsa_self = ospf_lsa_lock (new);
}
+ if (rt_recalc)
+ ospf_spf_calculate_schedule (ospf);
return new;
}
@@ -3292,6 +3294,9 @@ ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
if (l1->data->length == 0)
return 1;
+ if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
+ return 1; /* May be a stale LSA in the LSBD */
+
assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
p1 = (char *) l1->data;