summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Jakma <paul@quagga.net>2010-01-24 23:36:20 +0000
committerPaul Jakma <paul@quagga.net>2010-12-08 17:13:19 +0000
commit02d942c9d4afabf04bd781f0e1e5e8aa36945df2 (patch)
tree1874fc70a20b6b0407e808c926c362aa03415662
parentc363d3861b5384a31465a72ddc3b0f6ff007a95a (diff)
ospfd: Fix maxage/flush to not try flood twice, remember maxages for longer
2006-05-30 Paul Jakma <paul.jakma@sun.com> * (general) Fix confusion around MaxAge-ing and problem with high-latency networks. Analysis and suggested fixes by Phillip Spagnolo, in [quagga-dev 4132], on which this commit expands slightly. * ospf_flood.{c,h}: (ospf_lsa_flush) new function. Scope-general form of existing flush functions, essentially the dormant ospf_maxage_flood() but without the ambiguity of whether it is responsible for flooding. * ospf_lsa.c: (ospf_lsa_maxage) Role minimised to simply setup LSA on the Maxage list and schedule removal - no more. ospf_lsa_flush* being the primary way to kick-off flushes of LSAs. Don't hardcode the remover-timer value, which was too short for very high-latency networks. (ospf_maxage_lsa_remover) Just do what needs to be done to remove maxage LSAs from the maxage list, remove the call to ospf_flood_through(). Don't hardcode remove-timer value. (ospf_lsa_{install,flush_schedule}) ospf_lsa_flush is the correct entrypoint to flushing maxaged LSAs. (lsa_header_set) Use a define for the initial age, useful for testing. * ospf_opaque.c: (ospf_opaque_lsa_refresh) ditto. (ospf_opaque_lsa_flush_schedule) ditto. * ospfd.h: ({struct ospf,ospf_new}) Add maxage_delay parameter, interval to wait before running the maxage_remover. Supply a suitable default. Add a define for OSPF_LSA_INITIAL_AGE, see lsa_header_set().
-rw-r--r--ospfd/ospf_flood.c30
-rw-r--r--ospfd/ospf_flood.h1
-rw-r--r--ospfd/ospf_lsa.c54
-rw-r--r--ospfd/ospf_opaque.c4
-rw-r--r--ospfd/ospfd.c1
-rw-r--r--ospfd/ospfd.h7
6 files changed, 53 insertions, 44 deletions
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index 06d75740..77f2e161 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -991,3 +991,33 @@ ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa)
ospf_flood_through_as (ospf, NULL, lsa);
ospf_lsa_maxage (ospf, lsa);
}
+
+void
+ospf_lsa_flush (struct ospf *ospf, struct ospf_lsa *lsa)
+{
+ lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
+
+ switch (lsa->data->type)
+ {
+ case OSPF_ROUTER_LSA:
+ case OSPF_NETWORK_LSA:
+ case OSPF_SUMMARY_LSA:
+ case OSPF_ASBR_SUMMARY_LSA:
+ case OSPF_AS_NSSA_LSA:
+#ifdef HAVE_OPAQUE_LSA
+ case OSPF_OPAQUE_LINK_LSA:
+ case OSPF_OPAQUE_AREA_LSA:
+#endif /* HAVE_OPAQUE_LSA */
+ ospf_lsa_flush_area (lsa, lsa->area);
+ break;
+ case OSPF_AS_EXTERNAL_LSA:
+#ifdef HAVE_OPAQUE_LSA
+ case OSPF_OPAQUE_AS_LSA:
+#endif /* HAVE_OPAQUE_LSA */
+ ospf_lsa_flush_as (ospf, lsa);
+ break;
+ default:
+ zlog_info ("%s: Unknown LSA type %u", __func__, lsa->data->type);
+ break;
+ }
+}
diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h
index 5382e8fe..1ab11b88 100644
--- a/ospfd/ospf_flood.h
+++ b/ospfd/ospf_flood.h
@@ -66,6 +66,7 @@ extern void ospf_flood_lsa_area (struct ospf_lsa *, struct ospf_area *);
extern void ospf_flood_lsa_as (struct ospf_lsa *);
extern void ospf_lsa_flush_area (struct ospf_lsa *, struct ospf_area *);
extern void ospf_lsa_flush_as (struct ospf *, struct ospf_lsa *);
+extern void ospf_lsa_flush (struct ospf *, struct ospf_lsa *);
extern struct external_info *ospf_external_info_check (struct ospf_lsa *);
extern void ospf_lsdb_init (struct ospf_lsdb *);
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index bdc40151..6f5ee3db 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -372,7 +372,7 @@ lsa_header_set (struct stream *s, u_char options,
lsah = (struct lsa_header *) STREAM_DATA (s);
- lsah->ls_age = htons (0);
+ lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
lsah->options = options;
lsah->type = type;
lsah->id = id;
@@ -2762,7 +2762,7 @@ ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
new->data->type,
inet_ntoa (new->data->id),
lsa);
- ospf_lsa_maxage (ospf, lsa);
+ ospf_lsa_flush (ospf, lsa);
}
return new;
@@ -2794,35 +2794,6 @@ ospf_check_nbr_status (struct ospf *ospf)
}
-#ifdef ORIGINAL_CODING
-/* This function flood the maxaged LSA to DR. */
-void
-ospf_maxage_flood (struct ospf_lsa *lsa)
-{
- switch (lsa->data->type)
- {
- case OSPF_ROUTER_LSA:
- case OSPF_NETWORK_LSA:
- case OSPF_SUMMARY_LSA:
- case OSPF_ASBR_SUMMARY_LSA:
- case OSPF_AS_NSSA_LSA:
-#ifdef HAVE_OPAQUE_LSA
- case OSPF_OPAQUE_LINK_LSA:
- case OSPF_OPAQUE_AREA_LSA:
-#endif /* HAVE_OPAQUE_LSA */
- ospf_flood_through_area (lsa->area, NULL, lsa);
- break;
- case OSPF_AS_EXTERNAL_LSA:
-#ifdef HAVE_OPAQUE_LSA
- case OSPF_OPAQUE_AS_LSA:
-#endif /* HAVE_OPAQUE_LSA */
- ospf_flood_through_as (NULL, lsa);
- break;
- default:
- break;
- }
-}
-#endif /* ORIGINAL_CODING */
static int
ospf_maxage_lsa_remover (struct thread *thread)
@@ -2862,13 +2833,6 @@ ospf_maxage_lsa_remover (struct thread *thread)
zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
lsa->data->type, inet_ntoa (lsa->data->id));
- /* Flood max age LSA. */
-#ifdef ORIGINAL_CODING
- ospf_maxage_flood (lsa);
-#else /* ORIGINAL_CODING */
- ospf_flood_through (ospf, NULL, lsa);
-#endif /* ORIGINAL_CODING */
-
if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
{
if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
@@ -2892,7 +2856,8 @@ ospf_maxage_lsa_remover (struct thread *thread)
neighbor Link state retransmission lists and b) none of the router's
neighbors are in states Exchange or Loading. */
if (reschedule)
- OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
+ OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
+ ospf->maxage_delay);
return 0;
}
@@ -2910,6 +2875,11 @@ ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
}
}
+/* Add LSA onto the MaxAge list, and schedule for removal.
+ * This does *not* lead to the LSA being flooded, that must be taken
+ * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
+ * function).
+ */
void
ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
{
@@ -2929,7 +2899,8 @@ ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
- OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
+ OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
+ ospf->maxage_delay);
}
static int
@@ -3296,6 +3267,7 @@ ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
switch (lsa->data->type)
{
#ifdef HAVE_OPAQUE_LSA
+ /* Opaque wants to be notified of flushes */
case OSPF_OPAQUE_LINK_LSA:
case OSPF_OPAQUE_AREA_LSA:
case OSPF_OPAQUE_AS_LSA:
@@ -3303,7 +3275,7 @@ ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
break;
#endif /* HAVE_OPAQUE_LSA */
default:
- ospf_lsa_maxage (ospf, lsa);
+ ospf_lsa_flush (ospf, lsa);
break;
}
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 0b6ac4cb..6e90011e 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -1630,7 +1630,7 @@ ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)
zlog_debug ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa->data->type, inet_ntoa (lsa->data->id));
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
- ospf_lsa_maxage (ospf, lsa);
+ ospf_lsa_flush (ospf, lsa);
}
else
(* functab->lsa_refresher)(lsa);
@@ -2108,7 +2108,7 @@ ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
zlog_debug ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
/* This lsa will be flushed and removed eventually. */
- ospf_lsa_maxage (lsa0->area->ospf, lsa);
+ ospf_lsa_flush (lsa0->area->ospf, lsa);
out:
return;
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 7db81cea..0188ffda 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -199,6 +199,7 @@ ospf_new (void)
new->spf_hold_multiplier = 1;
/* MaxAge init. */
+ new->maxage_delay = OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
new->maxage_lsa = list_new ();
new->t_maxage_walker =
thread_add_timer (master, ospf_lsa_maxage_walker,
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index b7dc6762..0e57c452 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -58,6 +58,7 @@
#endif
#define OSPF_MIN_LS_INTERVAL 5
#define OSPF_MIN_LS_ARRIVAL 1
+#define OSPF_LSA_INITIAL_AGE 0 /* useful for debug */
#define OSPF_LSA_MAXAGE 3600
#define OSPF_CHECK_AGE 300
#define OSPF_LSA_MAXAGE_DIFF 900
@@ -66,7 +67,6 @@
#define OSPF_INITIAL_SEQUENCE_NUMBER 0x80000001
#define OSPF_MAX_SEQUENCE_NUMBER 0x7fffffff
-#define OSPF_LSA_MAXAGE_CHECK_INTERVAL 30
#define OSPF_NSSA_TRANS_STABLE_DEFAULT 40
#define OSPF_ALLSPFROUTERS 0xe0000005 /* 224.0.0.5 */
@@ -260,8 +260,13 @@ struct ospf
#ifdef HAVE_OPAQUE_LSA
struct thread *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */
#endif /* HAVE_OPAQUE_LSA */
+
+#define OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT 60
+ unsigned int maxage_delay; /* Delay on Maxage remover timer, sec */
struct thread *t_maxage; /* MaxAge LSA remover timer. */
+#define OSPF_LSA_MAXAGE_CHECK_INTERVAL 30
struct thread *t_maxage_walker; /* MaxAge LSA checking timer. */
+
struct thread *t_deferred_shutdown; /* deferred/stub-router shutdown timer*/
struct thread *t_write;