diff options
author | Dinesh Dutt <ddutt@cumulusnetworks.com> | 2012-12-04 19:46:37 +0100 |
---|---|---|
committer | Scott Feldman <sfeldma@cumulusnetworks.com> | 2013-01-07 18:59:43 +0100 |
commit | 91e6a0e5ca973c7183f638987b67aa370e9b484c (patch) | |
tree | 734c8c74baaaa6d3c303928b4f6d1d35d3394115 /ospfd/ospf_lsdb.c | |
parent | ospf: forward ref. of areas for "max-metric router-lsa administrative" cmd (diff) | |
download | frr-91e6a0e5ca973c7183f638987b67aa370e9b484c.tar.xz frr-91e6a0e5ca973c7183f638987b67aa370e9b484c.zip |
ospf: Convert MAX_AGE LSA list to tree
Store the MaxAge LSA list in a tree instead of a linked list for efficient access.
Walking the list can be quite inefficient in some large systems and under certain tests.
ospfd maintains the list of LSA's that have been MaxAge'd out in a separate
linked list for removal by a remover/walker thread. When a new LSA is to be
installed, the old LSA is ejected and when it is ejected, the MaxAge LSA list
is traversed to ensure that the old LSA is also removed from this list if it
exists on this list.
When a large number (> 5K) MaxAge LSAs are bombarding the system, walking this
list takes a significant time causing timers to fire and actions to be taken
such as expiring neighbors due to expiry of DeadInterval (especially when timer
is really low, <= 12s), creating a spiral of instability.
By making this MaxAge LSA list be a tree, this problem is mitigated.
Signed-off-by: Dinesh Dutt <ddutt@cumulusnetworks.com>
Reviewed-by: Ayan Banerjee <ayan@cumulusnetworks.com>
Reviewed-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Diffstat (limited to 'ospfd/ospf_lsdb.c')
-rw-r--r-- | ospfd/ospf_lsdb.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/ospfd/ospf_lsdb.c b/ospfd/ospf_lsdb.c index ea9a35284..aad979a74 100644 --- a/ospfd/ospf_lsdb.c +++ b/ospfd/ospf_lsdb.c @@ -72,13 +72,16 @@ ospf_lsdb_cleanup (struct ospf_lsdb *lsdb) route_table_finish (lsdb->type[i].db); } -static void -lsdb_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa) +void +ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa) { - lp->family = 0; - lp->prefixlen = 64; - lp->id = lsa->data->id; - lp->adv_router = lsa->data->adv_router; + if (lp && lsa && lsa->data) + { + lp->family = 0; + lp->prefixlen = 64; + lp->id = lsa->data->id; + lp->adv_router = lsa->data->adv_router; + } } static void @@ -115,7 +118,7 @@ ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) struct route_node *rn; table = lsdb->type[lsa->data->type].db; - lsdb_prefix_set (&lp, lsa); + ls_prefix_set (&lp, lsa); rn = route_node_get (table, (struct prefix *)&lp); /* nothing to do? */ @@ -167,7 +170,7 @@ ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) assert (lsa->data->type < OSPF_MAX_LSA); table = lsdb->type[lsa->data->type].db; - lsdb_prefix_set (&lp, lsa); + ls_prefix_set (&lp, lsa); if ((rn = route_node_lookup (table, (struct prefix *) &lp))) { if (rn->info == lsa) @@ -218,7 +221,7 @@ ospf_lsdb_lookup (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa) struct ospf_lsa *find; table = lsdb->type[lsa->data->type].db; - lsdb_prefix_set (&lp, lsa); + ls_prefix_set (&lp, lsa); rn = route_node_lookup (table, (struct prefix *) &lp); if (rn) { |