* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING. If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "prefix.h"
#include "table.h"
#include "memory.h"
+#include "log.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
-\f
+
struct ospf_lsdb *
ospf_lsdb_new ()
{
}
void
-lsdb_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
+ls_prefix_set (struct prefix_ls *lp, struct ospf_lsa *lsa)
{
- memset (lp, 0, sizeof (struct prefix_ls));
- 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
+ospf_lsdb_delete_entry (struct ospf_lsdb *lsdb, struct route_node *rn)
+{
+ struct ospf_lsa *lsa = rn->info;
+
+ if (!lsa)
+ return;
+
+ assert (rn->table == lsdb->type[lsa->data->type].db);
+
+ if (IS_LSA_SELF (lsa))
+ lsdb->type[lsa->data->type].count_self--;
+ lsdb->type[lsa->data->type].count--;
+ lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
+ lsdb->total--;
+ rn->info = NULL;
+ route_unlock_node (rn);
+#ifdef MONITOR_LSDB_CHANGE
+ if (lsdb->del_lsa_hook != NULL)
+ (* lsdb->del_lsa_hook)(lsa);
+#endif /* MONITOR_LSDB_CHANGE */
+ ospf_lsa_unlock (&lsa); /* lsdb */
+ return;
}
/* Add new LSA to lsdb. */
struct route_table *table;
struct prefix_ls lp;
struct route_node *rn;
- struct ospf_lsa *old;
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);
- if (!rn->info)
- {
- if (IS_LSA_SELF (lsa))
- lsdb->type[lsa->data->type].count_self++;
- lsdb->type[lsa->data->type].count++;
- lsdb->total++;
- }
- else
+
+ /* nothing to do? */
+ if (rn->info && rn->info == lsa)
{
- if (rn->info == lsa)
- return;
-
- old = rn->info;
- lsdb->type[old->data->type].checksum -= ntohs(old->data->checksum);
-
- ospf_lsa_unlock (rn->info);
route_unlock_node (rn);
+ return;
}
+
+ /* purge old entry? */
+ if (rn->info)
+ ospf_lsdb_delete_entry (lsdb, rn);
+
+ if (IS_LSA_SELF (lsa))
+ lsdb->type[lsa->data->type].count_self++;
+ lsdb->type[lsa->data->type].count++;
+ lsdb->total++;
#ifdef MONITOR_LSDB_CHANGE
if (lsdb->new_lsa_hook != NULL)
(* lsdb->new_lsa_hook)(lsa);
#endif /* MONITOR_LSDB_CHANGE */
lsdb->type[lsa->data->type].checksum += ntohs(lsa->data->checksum);
- rn->info = ospf_lsa_lock (lsa);
+ rn->info = ospf_lsa_lock (lsa); /* lsdb */
}
void
struct prefix_ls lp;
struct route_node *rn;
+ if (!lsdb)
+ {
+ zlog_warn ("%s: Called with NULL LSDB", __func__);
+ if (lsa)
+ zlog_warn ("LSA[Type%d:%s]: LSA %p, lsa->lsdb %p",
+ lsa->data->type, inet_ntoa (lsa->data->id),
+ (void *)lsa, (void *)lsa->lsdb);
+ return;
+ }
+
+ if (!lsa)
+ {
+ zlog_warn ("%s: Called with NULL LSA", __func__);
+ return;
+ }
+
+ assert (lsa->data->type < OSPF_MAX_LSA);
table = lsdb->type[lsa->data->type].db;
- lsdb_prefix_set (&lp, lsa);
- rn = route_node_lookup (table, (struct prefix *) &lp);
- if (rn)
- if (rn->info == lsa)
- {
- if (IS_LSA_SELF (lsa))
- lsdb->type[lsa->data->type].count_self--;
- lsdb->type[lsa->data->type].count--;
- lsdb->type[lsa->data->type].checksum -= ntohs(lsa->data->checksum);
- lsdb->total--;
- rn->info = NULL;
- route_unlock_node (rn);
- route_unlock_node (rn);
-#ifdef MONITOR_LSDB_CHANGE
- if (lsdb->del_lsa_hook != NULL)
- (* lsdb->del_lsa_hook)(lsa);
-#endif /* MONITOR_LSDB_CHANGE */
- ospf_lsa_unlock (lsa);
- return;
- }
+ ls_prefix_set (&lp, lsa);
+ if ((rn = route_node_lookup (table, (struct prefix *) &lp)))
+ {
+ if (rn->info == lsa)
+ ospf_lsdb_delete_entry (lsdb, rn);
+ route_unlock_node (rn); /* route_node_lookup */
+ }
}
void
{
struct route_table *table;
struct route_node *rn;
- struct ospf_lsa *lsa;
int i;
for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
{
table = lsdb->type[i].db;
for (rn = route_top (table); rn; rn = route_next (rn))
- if ((lsa = (rn->info)) != NULL)
- {
- if (IS_LSA_SELF (lsa))
- lsdb->type[i].count_self--;
- lsdb->type[i].count--;
- lsdb->type[i].checksum -= ntohs(lsa->data->checksum);
- lsdb->total--;
- rn->info = NULL;
- route_unlock_node (rn);
-#ifdef MONITOR_LSDB_CHANGE
- if (lsdb->del_lsa_hook != NULL)
- (* lsdb->del_lsa_hook)(lsa);
-#endif /* MONITOR_LSDB_CHANGE */
- ospf_lsa_unlock (lsa);
- }
+ if (rn->info != NULL)
+ ospf_lsdb_delete_entry (lsdb, rn);
}
}
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)
{
rn = route_top (table);
else
{
- rn = route_node_get (table, (struct prefix *) &lp);
+ if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL)
+ return NULL;
rn = route_next (rn);
}