2003-03-25 Paul Jakma <paul@dishone.st>

	* sync to latest zebra CVS
	* spec file: updated and added define for ospf-api/client

NB: OSPF-API has been broken by the zebra.org changes, which
has added struct ospf * as a new arg to many functions
diff --git a/ospfd/Makefile.am b/ospfd/Makefile.am
index 64d488a..16845e7 100644
--- a/ospfd/Makefile.am
+++ b/ospfd/Makefile.am
@@ -1,7 +1,6 @@
 ## Process this file with automake to produce Makefile.in.
 
 INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib
-LOCAL_OPTS = @OSPFAPI@
 DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA=@INSTALL@ -m 600
 
diff --git a/ospfd/Makefile.in b/ospfd/Makefile.in
index 907a2a7..aa16022 100644
--- a/ospfd/Makefile.in
+++ b/ospfd/Makefile.in
@@ -1,6 +1,7 @@
-# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+# Makefile.in generated automatically by automake 1.5 from Makefile.am.
 
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -10,6 +11,7 @@
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
+@SET_MAKE@
 
 SHELL = @SHELL@
 
@@ -31,13 +33,9 @@
 mandir = @mandir@
 includedir = @includedir@
 oldincludedir = /usr/include
-
-DESTDIR =
-
 pkgdatadir = $(datadir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
-
 top_builddir = ..
 
 ACLOCAL = @ACLOCAL@
@@ -46,11 +44,11 @@
 AUTOHEADER = @AUTOHEADER@
 
 INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_HEADER = $(INSTALL_DATA)
 transform = @program_transform_name@
-
 NORMAL_INSTALL = :
 PRE_INSTALL = :
 POST_INSTALL = :
@@ -59,21 +57,27 @@
 POST_UNINSTALL = :
 host_alias = @host_alias@
 host_triplet = @host@
+AMTAR = @AMTAR@
 AR = @AR@
+AWK = @AWK@
 BGPD = @BGPD@
 CC = @CC@
 CPP = @CPP@
 CURSES = @CURSES@
+DEPDIR = @DEPDIR@
+EXEEXT = @EXEEXT@
 IF_METHOD = @IF_METHOD@
 IF_PROC = @IF_PROC@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
 IPFORWARD = @IPFORWARD@
 KERNEL_METHOD = @KERNEL_METHOD@
 LIBPAM = @LIBPAM@
 LIB_IPV6 = @LIB_IPV6@
 LIB_REGEX = @LIB_REGEX@
-MAKEINFO = @MAKEINFO@
 MULTIPATH_NUM = @MULTIPATH_NUM@
+OBJEXT = @OBJEXT@
 OSPF6D = @OSPF6D@
+OSPFAPI = @OSPFAPI@
 OSPFCLIENT = @OSPFCLIENT@
 OSPFD = @OSPFD@
 OTHER_METHOD = @OTHER_METHOD@
@@ -86,13 +90,16 @@
 VERSION = @VERSION@
 VTYSH = @VTYSH@
 ZEBRA = @ZEBRA@
+am__include = @am__include@
+am__quote = @am__quote@
+install_sh = @install_sh@
 
 INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib
-LOCAL_OPTS = -DSUPPORT_OSPF_API
+LOCAL_OPTS = @OSPFAPI@
 DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
 INSTALL_SDATA = @INSTALL@ -m 600
 
-noinst_LIBRARIES = libospf.a
+lib_LIBRARIES = libospf.a
 sbin_PROGRAMS = ospfd
 
 libospf_a_SOURCES = \
@@ -103,12 +110,17 @@
 	ospf_opaque.c ospf_te.c ospf_vty.c ospf_api.c ospf_apiserver.c
 
 
+ospfdheaderdir = $(includedir)/ospfd
+
+ospfdheader_HEADERS = \
+	ospf_api.h ospf_asbr.h ospf_dump.h ospf_lsa.h ospf_lsdb.h \
+	ospf_nsm.h ospf_ism.h ospf_opaque.h ospfd.h
+
+
 noinst_HEADERS = \
-	ospf_dump.h ospf_interface.h ospf_ism.h ospf_neighbor.h \
-	ospf_network.h ospf_nsm.h ospf_packet.h ospf_zebra.h ospfd.h \
-	ospf_lsa.h ospf_spf.h ospf_route.h ospf_ase.h ospf_abr.h ospf_ia.h \
-	ospf_flood.h ospf_lsdb.h ospf_asbr.h ospf_snmp.h ospf_opaque.h \
-	ospf_te.h ospf_vty.h ospf_api.h ospf_apiserver.h
+	ospf_interface.h ospf_neighbor.h ospf_network.h ospf_packet.h \
+	ospf_zebra.h ospf_spf.h ospf_route.h ospf_ase.h ospf_abr.h ospf_ia.h \
+	ospf_flood.h ospf_snmp.h ospf_te.h ospf_vty.h ospf_apiserver.h
 
 
 ospfd_SOURCES = \
@@ -120,289 +132,355 @@
 sysconf_DATA = ospfd.conf.sample
 
 EXTRA_DIST = $(sysconf_DATA) OSPF-MIB.txt OSPF-TRAP-MIB.txt ChangeLog.opaque.txt
+subdir = ospfd
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = ../config.h
-CONFIG_CLEAN_FILES = 
-LIBRARIES =  $(noinst_LIBRARIES)
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(lib_LIBRARIES)
 
+libospf_a_AR = $(AR) cru
+libospf_a_LIBADD =
+am_libospf_a_OBJECTS = ospfd.$(OBJEXT) ospf_zebra.$(OBJEXT) \
+	ospf_interface.$(OBJEXT) ospf_ism.$(OBJEXT) \
+	ospf_neighbor.$(OBJEXT) ospf_nsm.$(OBJEXT) ospf_dump.$(OBJEXT) \
+	ospf_network.$(OBJEXT) ospf_packet.$(OBJEXT) ospf_lsa.$(OBJEXT) \
+	ospf_spf.$(OBJEXT) ospf_route.$(OBJEXT) ospf_ase.$(OBJEXT) \
+	ospf_abr.$(OBJEXT) ospf_ia.$(OBJEXT) ospf_flood.$(OBJEXT) \
+	ospf_lsdb.$(OBJEXT) ospf_asbr.$(OBJEXT) ospf_routemap.$(OBJEXT) \
+	ospf_snmp.$(OBJEXT) ospf_opaque.$(OBJEXT) ospf_te.$(OBJEXT) \
+	ospf_vty.$(OBJEXT) ospf_api.$(OBJEXT) ospf_apiserver.$(OBJEXT)
+libospf_a_OBJECTS = $(am_libospf_a_OBJECTS)
+sbin_PROGRAMS = ospfd$(EXEEXT)
+PROGRAMS = $(sbin_PROGRAMS)
+
+am_ospfd_OBJECTS = ospf_main.$(OBJEXT) ospfd.$(OBJEXT) \
+	ospf_zebra.$(OBJEXT) ospf_interface.$(OBJEXT) \
+	ospf_ism.$(OBJEXT) ospf_neighbor.$(OBJEXT) ospf_nsm.$(OBJEXT) \
+	ospf_dump.$(OBJEXT) ospf_network.$(OBJEXT) \
+	ospf_packet.$(OBJEXT) ospf_lsa.$(OBJEXT) ospf_spf.$(OBJEXT) \
+	ospf_route.$(OBJEXT) ospf_ase.$(OBJEXT) ospf_abr.$(OBJEXT) \
+	ospf_ia.$(OBJEXT) ospf_flood.$(OBJEXT) ospf_lsdb.$(OBJEXT) \
+	ospf_asbr.$(OBJEXT) ospf_routemap.$(OBJEXT) ospf_snmp.$(OBJEXT) \
+	ospf_opaque.$(OBJEXT) ospf_te.$(OBJEXT) ospf_vty.$(OBJEXT) \
+	ospf_api.$(OBJEXT) ospf_apiserver.$(OBJEXT)
+ospfd_OBJECTS = $(am_ospfd_OBJECTS)
+ospfd_DEPENDENCIES = ../lib/libzebra.a
+ospfd_LDFLAGS =
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-libospf_a_LIBADD = 
-libospf_a_OBJECTS =  ospfd.o ospf_zebra.o ospf_interface.o ospf_ism.o \
-ospf_neighbor.o ospf_nsm.o ospf_dump.o ospf_network.o ospf_packet.o \
-ospf_lsa.o ospf_spf.o ospf_route.o ospf_ase.o ospf_abr.o ospf_ia.o \
-ospf_flood.o ospf_lsdb.o ospf_asbr.o ospf_routemap.o ospf_snmp.o \
-ospf_opaque.o ospf_te.o ospf_vty.o ospf_api.o ospf_apiserver.o
-PROGRAMS =  $(sbin_PROGRAMS)
-
-ospfd_OBJECTS =  ospf_main.o ospfd.o ospf_zebra.o ospf_interface.o \
-ospf_ism.o ospf_neighbor.o ospf_nsm.o ospf_dump.o ospf_network.o \
-ospf_packet.o ospf_lsa.o ospf_spf.o ospf_route.o ospf_ase.o ospf_abr.o \
-ospf_ia.o ospf_flood.o ospf_lsdb.o ospf_asbr.o ospf_routemap.o \
-ospf_snmp.o ospf_opaque.o ospf_te.o ospf_vty.o ospf_api.o \
-ospf_apiserver.o
-ospfd_DEPENDENCIES =  ../lib/libzebra.a
-ospfd_LDFLAGS = 
-CFLAGS = @CFLAGS@
-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/ospf_abr.Po $(DEPDIR)/ospf_api.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_apiserver.Po $(DEPDIR)/ospf_asbr.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_ase.Po $(DEPDIR)/ospf_dump.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_flood.Po $(DEPDIR)/ospf_ia.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_interface.Po $(DEPDIR)/ospf_ism.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_lsa.Po $(DEPDIR)/ospf_lsdb.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_main.Po $(DEPDIR)/ospf_neighbor.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_network.Po $(DEPDIR)/ospf_nsm.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_opaque.Po $(DEPDIR)/ospf_packet.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_route.Po $(DEPDIR)/ospf_routemap.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_snmp.Po $(DEPDIR)/ospf_spf.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_te.Po $(DEPDIR)/ospf_vty.Po \
+@AMDEP_TRUE@	$(DEPDIR)/ospf_zebra.Po $(DEPDIR)/ospfd.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
-DATA =  $(sysconf_DATA)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+DIST_SOURCES = $(libospf_a_SOURCES) $(ospfd_SOURCES)
+DATA = $(sysconf_DATA)
 
-HEADERS =  $(noinst_HEADERS)
+HEADERS = $(noinst_HEADERS) $(ospfdheader_HEADERS)
 
-DIST_COMMON =  ChangeLog Makefile.am Makefile.in
-
-
-DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
-
-TAR = gtar
-GZIP_ENV = --best
-DEP_FILES =  .deps/ospf_abr.P .deps/ospf_api.P .deps/ospf_apiserver.P \
-.deps/ospf_asbr.P .deps/ospf_ase.P .deps/ospf_dump.P .deps/ospf_flood.P \
-.deps/ospf_ia.P .deps/ospf_interface.P .deps/ospf_ism.P \
-.deps/ospf_lsa.P .deps/ospf_lsdb.P .deps/ospf_main.P \
-.deps/ospf_neighbor.P .deps/ospf_network.P .deps/ospf_nsm.P \
-.deps/ospf_opaque.P .deps/ospf_packet.P .deps/ospf_route.P \
-.deps/ospf_routemap.P .deps/ospf_snmp.P .deps/ospf_spf.P \
-.deps/ospf_te.P .deps/ospf_vty.P .deps/ospf_zebra.P .deps/ospfd.P
+DIST_COMMON = $(noinst_HEADERS) $(ospfdheader_HEADERS) ChangeLog \
+	Makefile.am Makefile.in
 SOURCES = $(libospf_a_SOURCES) $(ospfd_SOURCES)
-OBJECTS = $(libospf_a_OBJECTS) $(ospfd_OBJECTS)
 
-all: all-redirect
+all: all-am
+
 .SUFFIXES:
-.SUFFIXES: .S .c .o .s
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
-	cd $(top_srcdir) && $(AUTOMAKE) --foreign ospfd/Makefile
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.ac $(ACLOCAL_M4)
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  ospfd/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+	cd $(top_builddir) && \
+	  CONFIG_HEADERS= CONFIG_LINKS= \
+	  CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
-	cd $(top_builddir) \
-	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+AR = ar
+install-libLIBRARIES: $(lib_LIBRARIES)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	@list='$(lib_LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo " $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \
+	    $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \
+	  else :; fi; \
+	done
+	@$(POST_INSTALL)
+	@list='$(lib_LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo " $(RANLIB) $(DESTDIR)$(libdir)/$$p"; \
+	    $(RANLIB) $(DESTDIR)$(libdir)/$$p; \
+	  else :; fi; \
+	done
 
+uninstall-libLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LIBRARIES)'; for p in $$list; do \
+	  echo " rm -f $(DESTDIR)$(libdir)/$$p"; \
+	  rm -f $(DESTDIR)$(libdir)/$$p; \
+	done
 
-mostlyclean-noinstLIBRARIES:
-
-clean-noinstLIBRARIES:
-	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
-
-distclean-noinstLIBRARIES:
-
-maintainer-clean-noinstLIBRARIES:
-
-.s.o:
-	$(COMPILE) -c $<
-
-.S.o:
-	$(COMPILE) -c $<
-
-mostlyclean-compile:
-	-rm -f *.o core *.core
-
-clean-compile:
-
-distclean-compile:
-	-rm -f *.tab.c
-
-maintainer-clean-compile:
-
-libospf.a: $(libospf_a_OBJECTS) $(libospf_a_DEPENDENCIES)
+clean-libLIBRARIES:
+	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
+libospf.a: $(libospf_a_OBJECTS) $(libospf_a_DEPENDENCIES) 
 	-rm -f libospf.a
-	$(AR) cru libospf.a $(libospf_a_OBJECTS) $(libospf_a_LIBADD)
+	$(libospf_a_AR) libospf.a $(libospf_a_OBJECTS) $(libospf_a_LIBADD)
 	$(RANLIB) libospf.a
-
-mostlyclean-sbinPROGRAMS:
-
-clean-sbinPROGRAMS:
-	-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
-
-distclean-sbinPROGRAMS:
-
-maintainer-clean-sbinPROGRAMS:
-
 install-sbinPROGRAMS: $(sbin_PROGRAMS)
 	@$(NORMAL_INSTALL)
 	$(mkinstalldirs) $(DESTDIR)$(sbindir)
 	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
-	  if test -f $$p; then \
-	    echo "  $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
-	     $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  if test -f $$p \
+	  ; then \
+	    f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
+	   echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/$$f"; \
+	   $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/$$f; \
 	  else :; fi; \
 	done
 
 uninstall-sbinPROGRAMS:
 	@$(NORMAL_UNINSTALL)
-	list='$(sbin_PROGRAMS)'; for p in $$list; do \
-	  rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
+	  f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \
+	  rm -f $(DESTDIR)$(sbindir)/$$f; \
 	done
 
-ospfd: $(ospfd_OBJECTS) $(ospfd_DEPENDENCIES)
-	@rm -f ospfd
+clean-sbinPROGRAMS:
+	-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+ospfd$(EXEEXT): $(ospfd_OBJECTS) $(ospfd_DEPENDENCIES) 
+	@rm -f ospfd$(EXEEXT)
 	$(LINK) $(ospfd_LDFLAGS) $(ospfd_OBJECTS) $(ospfd_LDADD) $(LIBS)
 
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_abr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_api.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_apiserver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_asbr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_ase.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_dump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_flood.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_ia.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_interface.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_ism.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_lsa.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_lsdb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_neighbor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_network.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_nsm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_opaque.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_packet.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_route.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_routemap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_snmp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_spf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_te.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_vty.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospf_zebra.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ospfd.Po@am__quote@
+
+distclean-depend:
+	-rm -rf $(DEPDIR)
+
+.c.o:
+@AMDEP_TRUE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+	$(COMPILE) -c `test -f $< || echo '$(srcdir)/'`$<
+
+.c.obj:
+@AMDEP_TRUE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+	$(COMPILE) -c `cygpath -w $<`
+CCDEPMODE = @CCDEPMODE@
+uninstall-info-am:
+
 uninstall-sysconfDATA:
 	@$(NORMAL_UNINSTALL)
-	list='$(sysconf_DATA)'; for p in $$list; do \
-	  rm -f $(DESTDIR)$(sysconfdir)/$$p; \
+	@list='$(sysconf_DATA)'; for p in $$list; do \
+	  f="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " rm -f $(DESTDIR)$(sysconfdir)/$$f"; \
+	  rm -f $(DESTDIR)$(sysconfdir)/$$f; \
+	done
+install-ospfdheaderHEADERS: $(ospfdheader_HEADERS)
+	@$(NORMAL_INSTALL)
+	$(mkinstalldirs) $(DESTDIR)$(ospfdheaderdir)
+	@list='$(ospfdheader_HEADERS)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " $(INSTALL_HEADER) $$d$$p $(DESTDIR)$(ospfdheaderdir)/$$f"; \
+	  $(INSTALL_HEADER) $$d$$p $(DESTDIR)$(ospfdheaderdir)/$$f; \
+	done
+
+uninstall-ospfdheaderHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(ospfdheader_HEADERS)'; for p in $$list; do \
+	  f="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " rm -f $(DESTDIR)$(ospfdheaderdir)/$$f"; \
+	  rm -f $(DESTDIR)$(ospfdheaderdir)/$$f; \
 	done
 
 tags: TAGS
 
-ID: $(HEADERS) $(SOURCES) $(LISP)
-	list='$(SOURCES) $(HEADERS)'; \
-	unique=`for i in $$list; do echo $$i; done | \
-	  awk '    { files[$$0] = 1; } \
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
 	       END { for (i in files) print i; }'`; \
-	here=`pwd` && cd $(srcdir) \
-	  && mkid -f$$here/ID $$unique $(LISP)
+	mkid -fID $$unique $(LISP)
 
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
 	tags=; \
 	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)'; \
-	unique=`for i in $$list; do echo $$i; done | \
-	  awk '    { files[$$0] = 1; } \
+	list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
 	       END { for (i in files) print i; }'`; \
 	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
-	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+	  || etags $(ETAGS_ARGS) $$tags  $$unique $(LISP)
 
-mostlyclean-tags:
-
-clean-tags:
+GTAGS:
+	here=`CDPATH=: && cd $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
 
 distclean-tags:
-	-rm -f TAGS ID
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
 
-maintainer-clean-tags:
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 
-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-
-subdir = ospfd
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
 
 distdir: $(DISTFILES)
-	here=`cd $(top_builddir) && pwd`; \
-	top_distdir=`cd $(top_distdir) && pwd`; \
-	distdir=`cd $(distdir) && pwd`; \
-	cd $(top_srcdir) \
-	  && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign ospfd/Makefile
 	@for file in $(DISTFILES); do \
-	  d=$(srcdir); \
+	  if test -f $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    $(mkinstalldirs) "$(distdir)/$$dir"; \
+	  fi; \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$d/$$file $(distdir)/$$file; \
+	    cp -pR $$d/$$file $(distdir) \
+	    || exit 1; \
 	  else \
 	    test -f $(distdir)/$$file \
-	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
-	    || cp -p $$d/$$file $(distdir)/$$file || :; \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
 	  fi; \
 	done
-
-DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
-
--include $(DEP_FILES)
-
-mostlyclean-depend:
-
-clean-depend:
-
-distclean-depend:
-	-rm -rf .deps
-
-maintainer-clean-depend:
-
-%.o: %.c
-	@echo '$(COMPILE) -c $<'; \
-	$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
-	@-cp .deps/$(*F).pp .deps/$(*F).P; \
-	tr ' ' '\012' < .deps/$(*F).pp \
-	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
-	    >> .deps/$(*F).P; \
-	rm .deps/$(*F).pp
-
-%.lo: %.c
-	@echo '$(LTCOMPILE) -c $<'; \
-	$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
-	@-sed -e 's/^\([^:]*\)\.o[ 	]*:/\1.lo \1.o :/' \
-	  < .deps/$(*F).pp > .deps/$(*F).P; \
-	tr ' ' '\012' < .deps/$(*F).pp \
-	  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
-	    >> .deps/$(*F).P; \
-	rm -f .deps/$(*F).pp
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
 check-am: all-am
 check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am: install-sbinPROGRAMS install-sysconfDATA
-install-exec: install-exec-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS)
 
-install-data-am:
+installdirs:
+	$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(sbindir) $(DESTDIR)$(sysconfdir) $(DESTDIR)$(ospfdheaderdir)
+
+install: install-am
+install-exec: install-exec-am
 install-data: install-data-am
+uninstall: uninstall-am
 
 install-am: all-am
 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am: uninstall-sbinPROGRAMS uninstall-sysconfDATA
-uninstall: uninstall-am
-all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS)
-all-redirect: all-am
+
+installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
-installdirs:
-	$(mkinstalldirs)  $(DESTDIR)$(sbindir) $(DESTDIR)$(sysconfdir)
-
-
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
 mostlyclean-generic:
 
 clean-generic:
 
 distclean-generic:
-	-rm -f Makefile $(CONFIG_CLEAN_FILES)
-	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
-		mostlyclean-sbinPROGRAMS mostlyclean-tags \
-		mostlyclean-depend mostlyclean-generic
-
-mostlyclean: mostlyclean-am
-
-clean-am:  clean-noinstLIBRARIES clean-compile clean-sbinPROGRAMS \
-		clean-tags clean-depend clean-generic mostlyclean-am
-
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-distclean-am:  distclean-noinstLIBRARIES distclean-compile \
-		distclean-sbinPROGRAMS distclean-tags distclean-depend \
-		distclean-generic clean-am
+clean-am: clean-generic clean-libLIBRARIES clean-sbinPROGRAMS \
+	mostlyclean-am
 
 distclean: distclean-am
 
-maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
-		maintainer-clean-compile maintainer-clean-sbinPROGRAMS \
-		maintainer-clean-tags maintainer-clean-depend \
-		maintainer-clean-generic distclean-am
-	@echo "This command is intended for maintainers to use;"
-	@echo "it deletes files that may require special tools to rebuild."
+distclean-am: clean-am distclean-compile distclean-depend \
+	distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-ospfdheaderHEADERS
+
+install-exec-am: install-libLIBRARIES install-sbinPROGRAMS \
+	install-sysconfDATA
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
 
 maintainer-clean: maintainer-clean-am
 
-.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
-clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
-mostlyclean-compile distclean-compile clean-compile \
-maintainer-clean-compile mostlyclean-sbinPROGRAMS \
-distclean-sbinPROGRAMS clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS \
-uninstall-sbinPROGRAMS install-sbinPROGRAMS uninstall-sysconfDATA \
-install-sysconfDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
-clean-depend maintainer-clean-depend info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-redirect all-am all installdirs mostlyclean-generic \
-distclean-generic clean-generic maintainer-clean-generic clean \
-mostlyclean distclean maintainer-clean
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+uninstall-am: uninstall-info-am uninstall-libLIBRARIES \
+	uninstall-ospfdheaderHEADERS uninstall-sbinPROGRAMS \
+	uninstall-sysconfDATA
+
+.PHONY: GTAGS all all-am check check-am clean clean-generic \
+	clean-libLIBRARIES clean-sbinPROGRAMS distclean \
+	distclean-compile distclean-depend distclean-generic \
+	distclean-tags distdir dvi dvi-am info info-am install \
+	install-am install-data install-data-am install-exec \
+	install-exec-am install-info install-info-am \
+	install-libLIBRARIES install-man install-ospfdheaderHEADERS \
+	install-sbinPROGRAMS install-strip install-sysconfDATA \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic tags uninstall uninstall-am \
+	uninstall-info-am uninstall-libLIBRARIES \
+	uninstall-ospfdheaderHEADERS uninstall-sbinPROGRAMS \
+	uninstall-sysconfDATA
 
 
 install-sysconfDATA: $(sysconf_DATA)
@@ -417,7 +495,6 @@
 	    $(INSTALL_SDATA) $$p $(DESTDIR)$(sysconfdir)/$$p; \
 	  fi; fi; \
 	done
-
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c
index 90ca230..3b2c055 100644
--- a/ospfd/ospf_apiserver.c
+++ b/ospfd/ospf_apiserver.c
@@ -1490,7 +1490,8 @@
     }
 
   /* Set opaque-LSA header fields. */
-  lsa_header_set (s, options, protolsa->type, protolsa->id);
+  lsa_header_set (s, options, protolsa->type, protolsa->id, 
+                  area->ospf->router_id);
 
   /* Set opaque-LSA body fields. */
   stream_put (s, ((u_char *) protolsa) + sizeof (struct lsa_header),
diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c
index 8eb7025..3747bc1 100644
--- a/ospfd/ospf_ase.c
+++ b/ospfd/ospf_ase.c
@@ -49,7 +49,8 @@
 #define DEBUG
 
 struct ospf_route *
-ospf_find_asbr_route (struct route_table *rtrs, struct prefix_ipv4 *asbr)
+ospf_find_asbr_route (struct ospf *ospf,
+		      struct route_table *rtrs, struct prefix_ipv4 *asbr)
 {
   struct route_node *rn;
   struct ospf_route *or, *best = NULL;
@@ -69,7 +70,7 @@
   chosen = list_new ();
 
   /* First try to find intra-area non-bb paths. */
-  if (!CHECK_FLAG (ospf_top->config, OSPF_RFC1583_COMPATIBLE))
+  if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
     for (node = listhead ((list) rn->info); node; nextnode (node))
       if ((or = getdata (node)) != NULL)
 	if (or->cost < OSPF_LS_INFINITY)
@@ -147,12 +148,12 @@
 }
 
 int
-ospf_ase_forward_address_check (struct in_addr fwd_addr)
+ospf_ase_forward_address_check (struct ospf *ospf, struct in_addr fwd_addr)
 {
   listnode ifn;
   struct ospf_interface *oi;
 
-  for (ifn = listhead (ospf_top->oiflist); ifn; nextnode (ifn))
+  for (ifn = listhead (ospf->oiflist); ifn; nextnode (ifn))
     if ((oi = getdata (ifn)) != NULL)
       if (if_is_operative (oi->ifp))
 	if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
@@ -164,7 +165,8 @@
 
 /* Calculate ASBR route. */
 struct ospf_route *
-ospf_ase_calculate_asbr_route (struct route_table *rt_network,
+ospf_ase_calculate_asbr_route (struct ospf *ospf,
+			       struct route_table *rt_network,
 			       struct route_table *rt_router,
 			       struct as_external_lsa *al)
 {
@@ -178,7 +180,7 @@
   asbr.prefixlen = IPV4_MAX_BITLEN;
   apply_mask_ipv4 (&asbr);
 
-  asbr_route = ospf_find_asbr_route (rt_router, &asbr);
+  asbr_route = ospf_find_asbr_route (ospf, rt_router, &asbr);
 
   if (asbr_route == NULL)
     {
@@ -198,7 +200,7 @@
       zlog_info ("ospf_ase_calculate(): "
 		 "Forwarding address is not 0.0.0.0.");
 
-      if (! ospf_ase_forward_address_check (al->e[0].fwd_addr))
+      if (! ospf_ase_forward_address_check (ospf, al->e[0].fwd_addr))
 	{
 	  zlog_info ("ospf_ase_calculate(): "
 		     "Forwarding address is one of our addresses, Ignore.");
@@ -279,7 +281,7 @@
 #define OSPF_ASE_CALC_INTERVAL 1
 
 int
-ospf_ase_calculate_route (struct ospf_lsa * lsa, void * p_arg, int n_arg)
+ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa)
 {
   u_int32_t metric;
   struct as_external_lsa *al;
@@ -343,7 +345,7 @@
   asbr.prefixlen = IPV4_MAX_BITLEN;
   apply_mask_ipv4 (&asbr);
   
-  asbr_route = ospf_find_asbr_route (ospf_top->new_rtrs, &asbr);
+  asbr_route = ospf_find_asbr_route (ospf, ospf->new_rtrs, &asbr);
   if (asbr_route == NULL)
     {
       zlog_info ("Route[External]: Can't find originating ASBR route");
@@ -383,7 +385,7 @@
 	 routing table entry must specify an intra-area or inter-area
 	 path; if no such path exists, do nothing with the LSA and
 	 consider the next in the list. */
-      if (! ospf_ase_forward_address_check (al->e[0].fwd_addr))
+      if (! ospf_ase_forward_address_check (ospf, al->e[0].fwd_addr))
 	{
 	  zlog_info ("Route[External]: Forwarding address is our router address");
 	  return 0;
@@ -393,7 +395,7 @@
       asbr.prefix = al->e[0].fwd_addr;
       asbr.prefixlen = IPV4_MAX_BITLEN;
 
-      rn = route_node_match (ospf_top->new_table, (struct prefix *) &asbr);
+      rn = route_node_match (ospf->new_table, (struct prefix *) &asbr);
       
       if (rn == NULL || (asbr_route = rn->info) == NULL)
 	{
@@ -437,7 +439,7 @@
 
   /* if there is a Intra/Inter area route to the N
      do not install external route */
-  if ((rn = route_node_lookup (ospf_top->new_table,
+  if ((rn = route_node_lookup (ospf->new_table,
 			       (struct prefix *) &p)) != NULL
       && (rn->info != NULL))
     {
@@ -448,14 +450,14 @@
   
   /* Find a route to the same dest */
   /* If there is no route, create new one. */
-  if ((rn = route_node_lookup (ospf_top->new_external_route,
+  if ((rn = route_node_lookup (ospf->new_external_route,
 			       (struct prefix *) &p)) == NULL 
       || (or = rn->info) == NULL)
     {
       zlog_info ("Route[External]: Adding a new route %s/%d",
 		 inet_ntoa (p.prefix), p.prefixlen);
 
-      ospf_route_add (ospf_top->new_external_route, &p, new, asbr_route);
+      ospf_route_add (ospf->new_external_route, &p, new, asbr_route);
 
       if (al->e[0].fwd_addr.s_addr)
 	ospf_ase_complete_direct_routes (new, al->e[0].fwd_addr);
@@ -470,7 +472,7 @@
              external paths. When all paths are type 2 external
 	     paths, the paths with the smallest advertised type 2
 	     metric are always preferred. */
-      ret = ospf_route_cmp (new, or);
+      ret = ospf_route_cmp (ospf, new, or);
   
   /*     (c) If the new AS external path is still indistinguishable
              from the current paths in the N's routing table entry,
@@ -610,10 +612,11 @@
 ospf_ase_calculate_timer (struct thread *t)
 {
   struct ospf *ospf;
-
+  struct ospf_lsa *lsa;
+  struct route_node *rn;
 #ifdef HAVE_NSSA
-      listnode node;
-      struct ospf_area *area;
+  listnode node;
+  struct ospf_area *area;
 #endif /* HAVE_NSSA */
 
   ospf = THREAD_ARG (t);
@@ -624,13 +627,13 @@
       ospf->ase_calc = 0;
 
       /* Calculate external route for each AS-external-LSA */
-      foreach_lsa (EXTERNAL_LSDB (ospf_top), NULL, 0,
-		   ospf_ase_calculate_route);
+      LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
+	ospf_ase_calculate_route (ospf, lsa);
 
 #ifdef HAVE_NSSA
       /*  This version simple adds to the table all NSSA areas  */
-      if (ospf_top->anyNSSA)
-	for (node = listhead (ospf_top->areas); node; nextnode (node))
+      if (ospf->anyNSSA)
+	for (node = listhead (ospf->areas); node; nextnode (node))
 	  {
 	    area = getdata (node);
 	    if (IS_DEBUG_OSPF_NSSA)
@@ -638,9 +641,8 @@
 			 inet_ntoa (area->area_id));
 
 	    if (area->external_routing == OSPF_AREA_NSSA)
-
-	      foreach_lsa (NSSA_LSDB (area), NULL, 0,
-			   ospf_ase_calculate_route);
+	      LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
+		ospf_ase_calculate_route (ospf, lsa);
 	  }
       /* kevinm: And add the NSSA routes in ospf_top */
       foreach_lsa(NSSA_LSDB (ospf_top), NULL, 0,
@@ -650,35 +652,35 @@
 
       /* Compare old and new external routing table and install the
 	 difference info zebra/kernel */
-      ospf_ase_compare_tables (ospf_top->new_external_route,
-			       ospf_top->old_external_route);
+      ospf_ase_compare_tables (ospf->new_external_route,
+			       ospf->old_external_route);
 
       /* Delete old external routing table */
-      ospf_route_table_free (ospf_top->old_external_route);
-      ospf_top->old_external_route = ospf_top->new_external_route;
-      ospf_top->new_external_route = route_table_init ();
+      ospf_route_table_free (ospf->old_external_route);
+      ospf->old_external_route = ospf->new_external_route;
+      ospf->new_external_route = route_table_init ();
     }
   return 0;
 }
 
 void
-ospf_ase_calculate_schedule ()
+ospf_ase_calculate_schedule (struct ospf *ospf)
 {
-  if (! ospf_top)
+  if (ospf == NULL)
     return;
 
-  ospf_top->ase_calc = 1;
+  ospf->ase_calc = 1;
 }
 
 void
-ospf_ase_calculate_timer_add ()
+ospf_ase_calculate_timer_add (struct ospf *ospf)
 {
-  if (! ospf_top)
+  if (ospf == NULL)
     return;
 
-  if (! ospf_top->t_ase_calc)
-    ospf_top->t_ase_calc = thread_add_timer (master, ospf_ase_calculate_timer,
-					     ospf_top, OSPF_ASE_CALC_INTERVAL);
+  if (! ospf->t_ase_calc)
+    ospf->t_ase_calc = thread_add_timer (master, ospf_ase_calculate_timer,
+					 ospf, OSPF_ASE_CALC_INTERVAL);
 }
 
 void
@@ -756,7 +758,7 @@
 }
 
 void
-ospf_ase_incremental_update (struct ospf_lsa *lsa, struct ospf *top)
+ospf_ase_incremental_update (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   list lsas;
   listnode node;
@@ -773,31 +775,31 @@
 
   /* if new_table is NULL, there was no spf calculation, thus
      incremental update is unneeded */
-  if (!top->new_table)
+  if (!ospf->new_table)
     return;
   
   /* If there is already an intra-area or inter-area route
      to the destination, no recalculation is necessary
      (internal routes take precedence). */
   
-  rn = route_node_lookup (top->new_table, (struct prefix *) &p);
+  rn = route_node_lookup (ospf->new_table, (struct prefix *) &p);
   if (rn && rn->info)
     {
       route_unlock_node (rn);
       return;
     }
 
-  rn = route_node_lookup (top->external_lsas, (struct prefix *) &p);
+  rn = route_node_lookup (ospf->external_lsas, (struct prefix *) &p);
   assert (rn && rn->info);
   lsas = rn->info;
   
   for (node = listhead (lsas); node; nextnode (node))
     if ((lsa = getdata (node)) != NULL)
-      ospf_ase_calculate_route (lsa, NULL, 0);
+      ospf_ase_calculate_route (ospf, lsa);
 
   /* prepare temporary old routing table for compare */
   tmp_old = route_table_init ();
-  rn = route_node_lookup (top->old_external_route, (struct prefix *) &p);
+  rn = route_node_lookup (ospf->old_external_route, (struct prefix *) &p);
   if (rn && rn->info)
     {
       rn2 = route_node_get (tmp_old, (struct prefix *) &p);
@@ -805,23 +807,23 @@
     }
 
   /* install changes to zebra */
-  ospf_ase_compare_tables (top->new_external_route, tmp_old);
+  ospf_ase_compare_tables (ospf->new_external_route, tmp_old);
 
-  /* update top->old_external_route table */
+  /* update ospf->old_external_route table */
   if (rn && rn->info)
     ospf_route_free ((struct ospf_route *) rn->info);
 
-  rn2 = route_node_lookup (top->new_external_route, (struct prefix *) &p);
-  /* if new route exists, install it to top->old_external_route */
+  rn2 = route_node_lookup (ospf->new_external_route, (struct prefix *) &p);
+  /* if new route exists, install it to ospf->old_external_route */
   if (rn2 && rn2->info)
     {
       if (!rn)
-	rn = route_node_get (top->old_external_route, (struct prefix *) &p);
+	rn = route_node_get (ospf->old_external_route, (struct prefix *) &p);
       rn->info = rn2->info;
     }
   else
     {
-      /* remove route node from top->old_external_route */
+      /* remove route node from ospf->old_external_route */
       if (rn)
 	{
 	  rn->info = NULL;
@@ -832,7 +834,7 @@
 
   if (rn2)
     {
-      /* rn2->info is stored in route node of top->old_external_route */
+      /* rn2->info is stored in route node of ospf->old_external_route */
       rn2->info = NULL;
       route_unlock_node (rn2);
       route_unlock_node (rn2);
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index 00a4c64..8c9a4c6 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -111,7 +111,8 @@
 }
 
 void
-ospf_process_self_originated_lsa (struct ospf_lsa *new, struct ospf_area *area)
+ospf_process_self_originated_lsa (struct ospf *ospf,
+				  struct ospf_lsa *new, struct ospf_area *area)
 {
   struct ospf_interface *oi;
   struct external_info *ei;
@@ -148,7 +149,7 @@
 
       /* Look through all interfaces, not just area, since interface
 	 could be moved from one area to another. */
-      for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+      for (node = listhead (ospf->oiflist); node; nextnode (node))
 	/* These are sanity check. */
 	if ((oi = getdata (node)) != NULL)
 	  if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &new->data->id))
@@ -179,7 +180,7 @@
       break;
     case OSPF_SUMMARY_LSA:
     case OSPF_ASBR_SUMMARY_LSA:
-      ospf_schedule_abr_task ();
+      ospf_schedule_abr_task (ospf);
       break;
     case OSPF_AS_EXTERNAL_LSA :
 #ifdef HAVE_NSSA
@@ -187,9 +188,9 @@
 #endif /* HAVE_NSSA */
       ei = ospf_external_info_check (new);
       if (ei)
-	ospf_external_lsa_refresh (new, ei, LSA_REFRESH_FORCE);
+	ospf_external_lsa_refresh (ospf, new, ei, LSA_REFRESH_FORCE);
       else
-	ospf_lsa_flush_as (new);
+	ospf_lsa_flush_as (ospf, new);
       break;
 #ifdef HAVE_OPAQUE_LSA
     case OSPF_OPAQUE_AREA_LSA:
@@ -229,8 +230,8 @@
 	    ABRs calculate external routes from Type-5's and non-self Type-7s
 */
 int
-ospf_flood (struct ospf_neighbor *nbr, struct ospf_lsa *current,
-	    struct ospf_lsa *new)
+ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr,
+	    struct ospf_lsa *current, struct ospf_lsa *new)
 {
   struct ospf_interface *oi;
   struct timeval now;
@@ -281,7 +282,7 @@
      DR and the LSA was received from a router other than the
      Backup DR) the LSA will be flooded back out the receiving
      interface. */
-  lsa_ack_flag = ospf_flood_through (nbr, new);
+  lsa_ack_flag = ospf_flood_through (ospf, nbr, new);
 
 #ifdef HAVE_OPAQUE_LSA
   /* Remove the current database copy from all neighbors' Link state
@@ -302,17 +303,17 @@
 #ifdef HAVE_OPAQUE_LSA
         case OSPF_OPAQUE_AS_LSA:
 #endif /* HAVE_OPAQUE_LSA */
-          ospf_ls_retransmit_delete_nbr_all (NULL, current);
+          ospf_ls_retransmit_delete_nbr_as (ospf, current);
           break;
         default:
-          ospf_ls_retransmit_delete_nbr_all (nbr->oi->area, current);
+          ospf_ls_retransmit_delete_nbr_area (nbr->oi->area, current);
           break;
         }
     }
 
   /* Do some internal house keeping that is needed here */
   SET_FLAG (new->flags, OSPF_LSA_RECEIVED);
-  ospf_lsa_is_self_originated (new); /* Let it set the flag */
+  ospf_lsa_is_self_originated (ospf, new); /* Let it set the flag */
 
   /* Install the new LSA in the link state database
      (replacing the current database copy).  This may cause the
@@ -321,15 +322,7 @@
      procedure cannot overwrite the newly installed LSA until
      MinLSArrival seconds have elapsed. */  
 
-  new = ospf_lsa_install (nbr->oi, new);
-
-#ifdef HAVE_NSSA 
-  if (IS_DEBUG_OSPF_NSSA)
-    zlog_info ("LSA[Flooding]: Type-%d installed", new->data->type);
-
-  /* if  (new->data->type == OSPF_AS_NSSA_LSA )
-     return 0;  */
-#endif /* HAVE_NSSA */
+  new = ospf_lsa_install (ospf, nbr->oi, new);
 
   /* Acknowledge the receipt of the LSA by sending a Link State
      Acknowledgment packet back out the receiving interface. */
@@ -340,11 +333,11 @@
      receiving router itself, the router must take special action,
      either updating the LSA or in some cases flushing it from
      the routing domain. */
-  if (ospf_lsa_is_self_originated (new))
-    ospf_process_self_originated_lsa (new, oi->area);
+  if (ospf_lsa_is_self_originated (ospf, new))
+    ospf_process_self_originated_lsa (ospf, new, oi->area);
   else
     /* Update statistics value for OSPF-MIB. */
-    ospf_top->rx_lsa_count++;
+    ospf->rx_lsa_count++;
 
   return 0;
 }
@@ -355,6 +348,7 @@
 			      struct ospf_neighbor *inbr,
 			      struct ospf_lsa *lsa)
 {
+  struct ospf *ospf = oi->ospf;
   struct ospf_neighbor *onbr;
   struct route_node *rn;
   int retx_flag;
@@ -440,7 +434,7 @@
               continue;
             }
 
-          if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (ospf_top->opaque)
+          if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (ospf->opaque)
           &&  IS_LSA_SELF (lsa)
           &&  onbr->state == NSM_Full)
             {
@@ -579,8 +573,8 @@
 }
 
 int
-ospf_flood_through_area (struct ospf_area * area,struct ospf_neighbor *inbr,
-			 struct ospf_lsa *lsa)
+ospf_flood_through_area (struct ospf_area *area,
+			 struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
 {
   listnode node;
   int lsa_ack_flag = 0;
@@ -618,7 +612,8 @@
 }
 
 int
-ospf_flood_through_as (struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
+ospf_flood_through_as (struct ospf *ospf, struct ospf_neighbor *inbr,
+		       struct ospf_lsa *lsa)
 {
   listnode node;
   int lsa_ack_flag;
@@ -643,7 +638,7 @@
       zlog_info ("Flood/AS: NSSA TRANSLATED LSA");
 #endif /* HAVE_NSSA */
 
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     {
       int continue_flag = 0;
       struct ospf_area *area = getdata (node);
@@ -659,13 +654,12 @@
 	case OSPF_AREA_NSSA:	/* Sending Type 5 or 7 into NSSA area */
 #ifdef HAVE_NSSA
 	  /* Type-7, flood NSSA area */
-          if (lsa->data->type == OSPF_AS_NSSA_LSA &&
-          	area == lsa->area) { 
+          if (lsa->data->type == OSPF_AS_NSSA_LSA
+	      && area == lsa->area)
 	    /* We will send it. */
 	    continue_flag = 0;
-          } else {
+          else
 	    continue_flag = 1;  /* Skip this NSSA area for Type-5's et al */
-	  }
           break;
 #endif /* HAVE_NSSA */
 
@@ -707,7 +701,8 @@
 }
 
 int
-ospf_flood_through (struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
+ospf_flood_through (struct ospf *ospf,
+		    struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
 {
   int lsa_ack_flag = 0;
   
@@ -736,7 +731,7 @@
 #ifdef HAVE_OPAQUE_LSA
     case OSPF_OPAQUE_AS_LSA:
 #endif /* HAVE_OPAQUE_LSA */
-      lsa_ack_flag = ospf_flood_through_as (inbr, lsa);
+      lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa);
       break;
 #ifdef HAVE_NSSA
       /* Type-7 Only received within NSSA, then flooded */
@@ -770,7 +765,7 @@
 #ifdef HAVE_OPAQUE_LSA
     case OSPF_OPAQUE_AS_LSA:
 #endif /* HAVE_OPAQUE_LSA */
-      lsa_ack_flag = ospf_flood_through_as (inbr, lsa);
+      lsa_ack_flag = ospf_flood_through_as (ospf, inbr, lsa);
       break;
 #ifdef HAVE_NSSA
       /* Type-7 Only received within NSSA, then flooded */
@@ -964,62 +959,44 @@
   return ospf_lsdb_lookup (&nbr->ls_rxmt, lsa);
 }
 
-/* Remove All neighbor/interface's Link State Retransmit list in area. */
 void
-ospf_ls_retransmit_delete_nbr_all (struct ospf_area *area,
-				   struct ospf_lsa *lsa)
+ospf_ls_retransmit_delete_nbr_if (struct ospf_interface *oi,
+				  struct ospf_lsa *lsa)
 {
-  listnode node;
-  list oiflist = area ? area->oiflist : ospf_top->oiflist;
-  
-  for (node = listhead (oiflist); node; nextnode (node))
-    {
-      struct ospf_interface *oi = getdata (node);
-      struct route_node *rn;
-      struct ospf_neighbor *nbr;
-      struct ospf_lsa *lsr;
-      
-      if (ospf_if_is_enable (oi))
-	for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
-	  /* If LSA find in LS-retransmit list, then remove it. */
-	  if ((nbr = rn->info) != NULL)
-	    {
-	      lsr = ospf_ls_retransmit_lookup (nbr, lsa);
+  struct route_node *rn;
+  struct ospf_neighbor *nbr;
+  struct ospf_lsa *lsr;
+
+  if (ospf_if_is_enable (oi))
+    for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
+      /* If LSA find in LS-retransmit list, then remove it. */
+      if ((nbr = rn->info) != NULL)
+	{
+	  lsr = ospf_ls_retransmit_lookup (nbr, lsa);
 	     
-	      /* If LSA find in ls-retransmit list, remove it. */
-	      if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
-		ospf_ls_retransmit_delete (nbr, lsr);
-	    }
-    }
+	  /* If LSA find in ls-retransmit list, remove it. */
+	  if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
+	    ospf_ls_retransmit_delete (nbr, lsr);
+	}
 }
 
-/* Add LSA to the current database copy of all neighbors'
-   Link state retransmission lists. */
 void
-ospf_ls_retransmit_add_nbr_all (struct ospf_interface *ospfi,
-				struct ospf_lsa *lsa)
+ospf_ls_retransmit_delete_nbr_area (struct ospf_area *area,
+				    struct ospf_lsa *lsa)
 {
   listnode node;
 
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
-    {
-      struct ospf_interface *oi = getdata (node);
-      struct route_node *rn;
-      struct ospf_neighbor *nbr;
-      struct ospf_lsa *old;
+  for (node = listhead (area->oiflist); node; nextnode (node))
+    ospf_ls_retransmit_delete_nbr_if (getdata (node), lsa);
+}
 
-      if (ospf_if_is_enable (oi))
-	if (OSPF_AREA_SAME (&ospfi->area, &oi->area))
-	  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
-	    if ((nbr = rn->info) != NULL)
-	      if (nbr->state == NSM_Full)
-		{
-		  if ((old = ospf_ls_retransmit_lookup (nbr, lsa)))
-		    ospf_ls_retransmit_delete (nbr, old);
+void
+ospf_ls_retransmit_delete_nbr_as (struct ospf *ospf, struct ospf_lsa *lsa)
+{
+  listnode node;
 
-		  ospf_ls_retransmit_add (nbr, lsa);
-		}
-    }
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
+    ospf_ls_retransmit_delete_nbr_if (getdata (node), lsa);
 }
 
 
@@ -1031,22 +1008,13 @@
 {
   lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
   ospf_flood_through_area (area, NULL, lsa);
-  ospf_lsa_maxage (lsa);
+  ospf_lsa_maxage (area->ospf, lsa);
 }
 
 void
-ospf_lsa_flush_as (struct ospf_lsa *lsa)
+ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
-  ospf_flood_through_as (NULL, lsa);
-  ospf_lsa_maxage (lsa);
-}
-
-/* Flush LSA through AS -- used for AS-external-LSAs. */
-void
-ospf_flush_through_as (struct ospf_lsa *lsa)
-{
-  lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
-  ospf_flood_through_as (NULL, lsa);
-  ospf_lsa_maxage (lsa);
+  ospf_flood_through_as (ospf, NULL, lsa);
+  ospf_lsa_maxage (ospf, lsa);
 }
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index d94cdb8..89ee8be 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -32,6 +32,7 @@
 #include "stream.h"
 #include "log.h"
 
+#include "ospfd/ospfd.h"
 #include "ospfd/ospf_spf.h"
 #include "ospfd/ospf_interface.h"
 #include "ospfd/ospf_ism.h"
@@ -42,7 +43,6 @@
 #include "ospfd/ospf_nsm.h"
 #include "ospfd/ospf_packet.h"
 #include "ospfd/ospf_abr.h"
-#include "ospfd/ospfd.h"
 #include "ospfd/ospf_network.h"
 #include "ospfd/ospf_dump.h"
 #ifdef HAVE_SNMP
@@ -58,7 +58,7 @@
   u_int32_t bw, refbw;
 
   bw = oi->ifp->bandwidth ? oi->ifp->bandwidth : OSPF_DEFAULT_BANDWIDTH;
-  refbw = ospf_top ? ospf_top->ref_bandwidth : OSPF_DEFAULT_REF_BANDWIDTH;
+  refbw = oi->ospf->ref_bandwidth;
 
   /* A specifed ip ospf cost overrides a calculated one. */
   if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), output_cost_cmd) ||
@@ -160,7 +160,7 @@
 }
 
 struct ospf_interface *
-ospf_if_new (struct interface *ifp, struct prefix *p)
+ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p)
 {
   struct ospf_interface *oi;
 
@@ -172,7 +172,7 @@
   oi->address = p;
   
   ospf_add_to_if (ifp, oi);
-  listnode_add (ospf_top->oiflist, oi);
+  listnode_add (ospf->oiflist, oi);
   
   /* Clear self-originated network-LSA. */
   oi->network_lsa_self = NULL;
@@ -193,7 +193,6 @@
   /* Add pseudo neighbor. */
   oi->nbr_self = ospf_nbr_new (oi);
   oi->nbr_self->state = NSM_TwoWay;
-  /*  oi->nbr_self->router_id = ospf_top->router_id; */
   oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
   oi->nbr_self->options = OSPF_OPTION_E;
 
@@ -201,11 +200,13 @@
   oi->t_ls_upd_event = NULL;
   oi->t_ls_ack_direct = NULL;
 
+  oi->crypt_seqnum = time (NULL);
+
 #ifdef HAVE_OPAQUE_LSA
   ospf_opaque_type9_lsa_init (oi);
 #endif /* HAVE_OPAQUE_LSA */
 
-  oi->ospf = ospf_top;
+  oi->ospf = ospf;
   
   return oi;
 }
@@ -307,7 +308,7 @@
   
   ospf_delete_from_if (oi->ifp, oi);
 
-  listnode_delete (ospf_top->oiflist, oi);
+  listnode_delete (oi->ospf->oiflist, oi);
   listnode_delete (oi->area->oiflist, oi);
 
   memset (oi, 0, sizeof (*oi));
@@ -320,13 +321,13 @@
 *  return it if yes.
 */
 struct ospf_interface *
-ospf_if_is_configured (struct in_addr *address)
+ospf_if_is_configured (struct ospf *ospf, struct in_addr *address)
 {
   listnode node;
   struct ospf_interface *oi;
   struct prefix *addr;
   
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
     if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK)
       {
 	if (oi->type == OSPF_IFTYPE_POINTOPOINT)
@@ -348,12 +349,13 @@
 }
 
 struct ospf_interface *
-ospf_if_lookup_by_local_addr (struct interface *ifp, struct in_addr address)
+ospf_if_lookup_by_local_addr (struct ospf *ospf,
+			      struct interface *ifp, struct in_addr address)
 {
   listnode node;
   struct ospf_interface *oi;
   
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
     if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK)
       {
 	if (ifp && oi->ifp != ifp)
@@ -367,34 +369,36 @@
 }
 
 struct ospf_interface *
-ospf_if_lookup_by_prefix (struct prefix_ipv4 *p)
+ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p)
 {
   listnode node;
   struct ospf_interface *oi;
   struct prefix ptmp;
   
   /* Check each Interface. */
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node)) {
-    if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK)
-      {
-	if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
-	  prefix_copy (&ptmp, oi->connected->destination);
-	  ptmp.prefixlen = IPV4_MAX_BITLEN;
-	}
-	else
-	  prefix_copy (&ptmp, oi->address);
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
+    {
+      if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK)
+	{
+	  if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+	    {
+	      prefix_copy (&ptmp, oi->connected->destination);
+	      ptmp.prefixlen = IPV4_MAX_BITLEN;
+	    }
+	  else
+	    prefix_copy (&ptmp, oi->address);
 	
-	apply_mask (&ptmp);
-	if (prefix_same (&ptmp, (struct prefix *) p))
-	  return oi;
-      }
-  }
+	  apply_mask (&ptmp);
+	  if (prefix_same (&ptmp, (struct prefix *) p))
+	    return oi;
+	}
+    }
   return NULL;
 }
 
 /* determine receiving interface by source of packet */
 struct ospf_interface *
-ospf_if_lookup_recv_interface (struct in_addr src)
+ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src)
 {
   listnode node;
   struct prefix_ipv4 addr;
@@ -406,7 +410,7 @@
 
   match = NULL;
 
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
     {
       oi = getdata (node);
       
@@ -439,6 +443,8 @@
 void
 ospf_if_stream_unset (struct ospf_interface *oi)
 {
+  struct ospf *ospf = oi->ospf;
+
   if (oi->obuf)
     {
      ospf_fifo_free (oi->obuf);
@@ -446,13 +452,14 @@
 
      if (oi->on_write_q)
        {
-	 listnode_delete (ospf_top->oi_write_q, oi);
-         if (list_isempty(ospf_top->oi_write_q))
-           OSPF_TIMER_OFF (ospf_top->t_write);
+	 listnode_delete (ospf->oi_write_q, oi);
+         if (list_isempty(ospf->oi_write_q))
+           OSPF_TIMER_OFF (ospf->t_write);
 	 oi->on_write_q = 0;
        }
     }
 }
+
 
 struct ospf_if_params *
 ospf_new_if_params ()
@@ -662,7 +669,7 @@
   else
     {
       if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
-	ospf_if_add_allspfrouters (ospf_top, oi->address, oi->ifp->ifindex);
+	ospf_if_add_allspfrouters (oi->ospf, oi->address, oi->ifp->ifindex);
       ospf_if_stream_set (oi);
       OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
     }
@@ -680,7 +687,7 @@
   /* Shutdown packet reception and sending */
   ospf_if_stream_unset (oi);
   if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
-    ospf_if_drop_allspfrouters (ospf_top, oi->address, oi->ifp->ifindex);
+    ospf_if_drop_allspfrouters (oi->ospf, oi->address, oi->ifp->ifindex);
 
 
   return 1;
@@ -713,7 +720,7 @@
 u_int vlink_count = 0;
 
 struct ospf_interface * 
-ospf_vl_new (struct ospf_vl_data *vl_data)
+ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data)
 {
   struct ospf_interface * voi;
   struct interface * vi;
@@ -748,7 +755,7 @@
  
   co->address = (struct prefix *)p;
   
-  voi = ospf_if_new (vi, co->address);
+  voi = ospf_if_new (ospf, vi, co->address);
   if (voi == NULL)
     {
       if (IS_DEBUG_OSPF_EVENT)
@@ -768,7 +775,7 @@
     zlog_info ("ospf_vl_new(): set if->name to %s", vi->name);
 
   area_id.s_addr = 0;
-  area = ospf_area_get (area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
+  area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
   voi->area = area;
 
   if (IS_DEBUG_OSPF_EVENT)
@@ -800,7 +807,7 @@
   struct ospf_vl_data *vl_data;
   listnode node;
 
-  for (node = listhead (ospf_top->vlinks); node; nextnode (node))
+  for (node = listhead (area->ospf->vlinks); node; nextnode (node))
     if ((vl_data = getdata (node)) != NULL)
       if (vl_data->vl_peer.s_addr == vl_peer.s_addr &&
           IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
@@ -826,16 +833,16 @@
 }
 
 void
-ospf_vl_add (struct ospf_vl_data *vl_data)
+ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
 {
-  listnode_add (ospf_top->vlinks, vl_data);
+  listnode_add (ospf->vlinks, vl_data);
 #ifdef HAVE_SNMP
   ospf_snmp_vl_add (vl_data);
 #endif /* HAVE_SNMP */
 }
 
 void
-ospf_vl_delete (struct ospf_vl_data *vl_data)
+ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
 {
   ospf_vl_shutdown (vl_data);
   ospf_vl_if_delete (vl_data);
@@ -843,7 +850,7 @@
 #ifdef HAVE_SNMP
   ospf_snmp_vl_delete (vl_data);
 #endif /* HAVE_SNMP */
-  listnode_delete (ospf_top->vlinks, vl_data);
+  listnode_delete (ospf->vlinks, vl_data);
 
   ospf_vl_data_free (vl_data);
 }
@@ -899,9 +906,10 @@
 
 
 void
-ospf_vl_up_check (struct ospf_area * area, struct in_addr rid,
+ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,
                   struct vertex *v)
 {
+  struct ospf *ospf = area->ospf;
   listnode node;
   struct ospf_vl_data *vl_data;
   struct ospf_interface *oi;
@@ -913,7 +921,7 @@
       zlog_info ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id));
     }
 
-  for (node = listhead (ospf_top->vlinks); node; nextnode (node))
+  for (node = listhead (ospf->vlinks); node; nextnode (node))
     {
       if ((vl_data = getdata (node)) == NULL)
         continue;
@@ -950,23 +958,23 @@
 }
 
 void
-ospf_vl_unapprove ()
+ospf_vl_unapprove (struct ospf *ospf)
 {
   listnode node;
   struct ospf_vl_data *vl_data;
 
-  for (node = listhead (ospf_top->vlinks); node; nextnode (node))
+  for (node = listhead (ospf->vlinks); node; nextnode (node))
     if ((vl_data = getdata (node)) != NULL)
       UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
 }
 
 void
-ospf_vl_shut_unapproved ()
+ospf_vl_shut_unapproved (struct ospf *ospf)
 {
   listnode node;
   struct ospf_vl_data *vl_data;
 
-  for (node = listhead (ospf_top->vlinks); node; nextnode (node))
+  for (node = listhead (ospf->vlinks); node; nextnode (node))
     if ((vl_data = getdata (node)) != NULL)
       if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED))
         ospf_vl_shutdown (vl_data);
@@ -992,7 +1000,7 @@
   struct ospf_vl_data *vl_data;
   int c = 0;
 
-  for (node = listhead (ospf_top->vlinks); node; nextnode (node))
+  for (node = listhead (area->ospf->vlinks); node; nextnode (node))
     if ((vl_data = getdata (node)) != NULL)
       if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
         c++;
diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c
index b47487f..5f4d546 100644
--- a/ospfd/ospf_ism.c
+++ b/ospfd/ospf_ism.c
@@ -192,7 +192,7 @@
 
 /* Generate AdjOK? NSM event. */
 void
-ospf_dr_change (struct route_table *nbrs)
+ospf_dr_change (struct ospf *ospf, struct route_table *nbrs)
 {
   struct route_node *rn;
   struct ospf_neighbor *nbr;
@@ -204,7 +204,7 @@
 	/* Is neighbor upper 2-Way? */
 	if (nbr->state >= NSM_TwoWay)
 	  /* Ignore myself. */
-	  if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
+	  if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf->router_id))
 	    OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_AdjOK);
 }
 
@@ -252,17 +252,17 @@
   /* if DR or BDR changes, cause AdjOK? neighbor event. */
   if (!IPV4_ADDR_SAME (&old_dr, &DR (oi)) ||
       !IPV4_ADDR_SAME (&old_bdr, &BDR (oi)))
-    ospf_dr_change (oi->nbrs);
+    ospf_dr_change (oi->ospf, oi->nbrs);
 
   if (oi->type == OSPF_IFTYPE_BROADCAST || oi->type == OSPF_IFTYPE_POINTOPOINT)
     {
       /* Multicast group change. */
       if ((old_state != ISM_DR && old_state != ISM_Backup) &&
 	  (new_state == ISM_DR || new_state == ISM_Backup))
-	ospf_if_add_alldrouters (ospf_top, oi->address, oi->ifp->ifindex);
+	ospf_if_add_alldrouters (oi->ospf, oi->address, oi->ifp->ifindex);
       else if ((old_state == ISM_DR || old_state == ISM_Backup) &&
 	       (new_state != ISM_DR && new_state != ISM_Backup))
-	ospf_if_drop_alldrouters (ospf_top, oi->address, oi->ifp->ifindex);
+	ospf_if_drop_alldrouters (oi->ospf, oi->address, oi->ifp->ifindex);
     }
 
   return new_state;
@@ -404,7 +404,7 @@
     next_state = ISM_Waiting;
 
   if (oi->type == OSPF_IFTYPE_NBMA)
-    ospf_nbr_nbma_if_update (oi);
+    ospf_nbr_nbma_if_update (oi->ospf, oi);
 
   /*  ospf_ism_event (t); */
   return next_state;
@@ -582,7 +582,7 @@
   oi->state_change++;
 
   if (old_state == ISM_Down || state == ISM_Down)
-    ospf_check_abr_status();
+    ospf_check_abr_status (oi->ospf);
 
   /* Originate router-LSA. */
   if (oi->area)
@@ -621,7 +621,7 @@
 #endif /* HAVE_OPAQUE_LSA */
 
   /* Check area border status.  */
-  ospf_check_abr_status ();
+  ospf_check_abr_status (oi->ospf);
 }
 
 /* Execute ISM event process. */
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 9c8cd81..e01dbd0 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -394,7 +394,7 @@
 
 void
 lsa_header_set (struct stream *s, u_char options,
-		u_char type, struct in_addr id)
+		u_char type, struct in_addr id, struct in_addr router_id)
 {
   struct lsa_header *lsah;
 
@@ -404,12 +404,13 @@
   lsah->options = options;
   lsah->type = type;
   lsah->id = id;
-  lsah->adv_router = ospf_top->router_id;
+  lsah->adv_router = router_id;
   lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
 
   ospf_output_forward (s, OSPF_LSA_HEADER_SIZE);
 }
 
+
 /* router-LSA related functions. */
 /* Get router-LSA flags. */
 u_char
@@ -417,7 +418,7 @@
 {
   u_char flags;
 
-  flags = ospf_top->flags;
+  flags = area->ospf->flags;
 
   /* Set virtual link flag. */
   if (ospf_full_virtual_nbrs (area))
@@ -428,10 +429,10 @@
 
   /* Set Shortcut ABR behabiour flag. */
   UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
-  if (ospf_top->abr_type == OSPF_ABR_SHORTCUT)
+  if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
     if (!OSPF_IS_AREA_BACKBONE (area))
       if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
-	   !ospf_top->backbone) ||
+	   area->ospf->backbone == NULL) ||
 	  area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
 	SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
 
@@ -446,21 +447,23 @@
    And check neighbor count,
    Point-to-Point link must have only 1 neighbor. */
 struct ospf_neighbor *
-ospf_nbr_lookup_ptop (struct route_table *nbrs, struct in_addr router_id)
+ospf_nbr_lookup_ptop (struct ospf_interface *oi)
 {
-  struct route_node *rn;
   struct ospf_neighbor *nbr = NULL;
+  struct route_node *rn;
 
   /* Search neighbor, there must be one of two nbrs. */
-  for (rn = route_top (nbrs); rn; rn = route_next (rn))
-    if ((nbr = rn->info) != NULL)
-      /* Ignore myself. */
-      if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
+  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
+    if ((nbr = rn->info))
+      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
 	if (nbr->state == NSM_Full)
-	  break;
+	  {
+	    route_unlock_node (rn);
+	    break;
+	  }
 
   /* PtoP link must have only 1 neighbor. */
-  if (ospf_nbr_count (nbrs, 0) > 1)
+  if (ospf_nbr_count (oi, 0) > 1)
     zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
 
   return nbr;
@@ -490,7 +493,7 @@
   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
     zlog_info ("LSA[Type1]: Set link Point-to-Point");
 
-  if ((nbr = ospf_nbr_lookup_ptop (oi->nbrs, ospf_top->router_id)))
+  if ((nbr = ospf_nbr_lookup_ptop (oi)))
     if (nbr->state == NSM_Full)
       {
 	/* For unnumbered point-to-point networks, the Link Data field
@@ -545,7 +548,7 @@
   /* Describe Type 2 link. */
   if (dr && (dr->state == NSM_Full ||
 	     IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
-      ospf_nbr_count (oi->nbrs, NSM_Full) > 0)
+      ospf_nbr_count (oi, NSM_Full) > 0)
     {
       link_info_set (s, DR (oi), oi->address->u.prefix4,
 		     LSA_LINK_TYPE_TRANSIT, 0, oi->output_cost);
@@ -581,11 +584,8 @@
 {
   struct ospf_neighbor *nbr;
 
-  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
-    zlog_info ("LSA[Type1]: Set link type VL, state %d", oi->state);
-
   if (oi->state == ISM_PointToPoint)
-    if ((nbr = ospf_nbr_lookup_ptop (oi->nbrs, ospf_top->router_id)))
+    if ((nbr = ospf_nbr_lookup_ptop (oi)))
       if (nbr->state == NSM_Full)
 	{
 	  link_info_set (s, nbr->router_id, oi->address->u.prefix4,
@@ -602,7 +602,8 @@
 12.4.1.4.*/
 /* from "edward rrr" <edward_rrr@hotmail.com>
    http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
-int lsa_link_ptomultip_set (struct stream *s, struct ospf_interface *oi)
+int
+lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
 {
   int links = 0;
   struct route_node *rn;
@@ -620,11 +621,10 @@
   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
     if ((nbr = rn->info) != NULL)
       /* Ignore myself. */
-      if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
+      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
 	if (nbr->state == NSM_Full)
 
 	  {
-	    
 	    link_info_set (s, nbr->router_id, oi->address->u.prefix4,
 			   LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
 	    links++;
@@ -633,7 +633,6 @@
 	  }
   
   return links;
-  
 }
 
 /* Set router-LSA link information. */
@@ -666,7 +665,7 @@
 		  links += lsa_link_nbma_set (s, oi);
 		  break;
 		case OSPF_IFTYPE_POINTOMULTIPOINT:
-		  links += lsa_link_ptomultip_set (s, oi);
+		  links += lsa_link_ptomp_set (s, oi);
 		  break;
 		case OSPF_IFTYPE_VIRTUALLINK:
 		  links += lsa_link_virtuallink_set (s, oi);
@@ -711,6 +710,7 @@
 struct ospf_lsa *
 ospf_router_lsa_new (struct ospf_area *area)
 {
+  struct ospf *ospf = area->ospf;
   struct stream *s;
   struct lsa_header *lsah;
   struct ospf_lsa *new;
@@ -726,11 +726,11 @@
 #ifdef HAVE_NSSA
   /* Set LSA common header fields. */
   lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_NSSA_GET (area),
-		  OSPF_ROUTER_LSA, ospf_top->router_id);
+		  OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
 #else /* ! HAVE_NSSA */
   /* Set LSA common header fields. */
   lsa_header_set (s, LSA_OPTIONS_GET (area),
-		  OSPF_ROUTER_LSA, ospf_top->router_id);
+		  OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
 #endif /* HAVE_NSSA */
 
   /* Set router-LSA body fields. */
@@ -772,10 +772,10 @@
     }
 
   /* Install LSA to LSDB. */
-  new = ospf_lsa_install (NULL, new);
+  new = ospf_lsa_install (area->ospf, NULL, new);
 
   /* Update LSA origination count. */
-  ospf_top->lsa_originate_count++;
+  area->ospf->lsa_originate_count++;
 
   /* Flooding new LSA through area. */
   ospf_flood_through_area (area, NULL, new);
@@ -801,13 +801,13 @@
   assert (lsa->data);
 
   /* Delete LSA from neighbor retransmit-list. */
-  ospf_ls_retransmit_delete_nbr_all (area, lsa);
+  ospf_ls_retransmit_delete_nbr_area (area, lsa);
 
   /* Create new router-LSA instance. */
   new = ospf_router_lsa_new (area);
   new->data->ls_seqnum = lsa_seqnum_increment (lsa);
 
-  ospf_lsa_install (NULL, new);
+  ospf_lsa_install (area->ospf, NULL, new);
 
   /* Flood LSA through area. */
   ospf_flood_through_area (area, NULL, new);
@@ -877,16 +877,17 @@
 }
 
 int
-ospf_router_lsa_update_timer (struct thread *t)
+ospf_router_lsa_update_timer (struct thread *thread)
 {
+  struct ospf *ospf = THREAD_ARG (thread);
   listnode node;
 
   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
     zlog_info ("Timer[router-LSA Update]: (timer expire)");
 
-  ospf_top->t_router_lsa_update = NULL;
+  ospf->t_router_lsa_update = NULL;
 
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     {
       struct ospf_area *area = getdata (node);
       struct ospf_lsa *lsa = area->router_lsa_self;
@@ -906,7 +907,7 @@
         }
       /* If router-ID is changed, Link ID must change.
 	 First flush old LSA, then originate new. */
-      else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf_top->router_id))
+      else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
 	{
 	  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
 	    zlog_info("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
@@ -922,7 +923,7 @@
 	{
 	  rl = (struct router_lsa *) lsa->data;
 	  /* Refresh router-LSA, (not install) and flood through area. */
-	  if (rl->flags != ospf_top->flags)
+	  if (rl->flags != ospf->flags)
 	    ospf_router_lsa_timer_add (area);
 	}
     }
@@ -975,7 +976,7 @@
   lsah = (struct lsa_header *) STREAM_DATA (s);
 
   lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
-		  OSPF_NETWORK_LSA, DR (oi));
+		  OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
 
   /* Set network-LSA body fields. */
   ospf_network_lsa_body_set (s, oi);
@@ -1009,10 +1010,10 @@
     return NULL;
 
   /* Install LSA to LSDB. */
-  new = ospf_lsa_install (oi, new);
+  new = ospf_lsa_install (oi->ospf, oi, new);
 
   /* Update LSA origination count. */
-  ospf_top->lsa_originate_count++;
+  oi->ospf->lsa_originate_count++;
 
   /* Flooding new LSA through area. */
   ospf_flood_through_area (oi->area, NULL, new);
@@ -1036,7 +1037,7 @@
   assert (lsa->data);
 
   /* Delete LSA from neighbor retransmit-list. */
-  ospf_ls_retransmit_delete_nbr_all (area, lsa);
+  ospf_ls_retransmit_delete_nbr_area (area, lsa);
 
   /* Create new network-LSA instance. */
   new = ospf_network_lsa_new (oi);
@@ -1044,7 +1045,7 @@
     return -1;
   new->data->ls_seqnum = lsa_seqnum_increment (lsa);
 
-  ospf_lsa_install (oi, new);
+  ospf_lsa_install (area->ospf, oi, new);
 
   /* Flood LSA through aera. */
   ospf_flood_through_area (area, NULL, new);
@@ -1159,7 +1160,8 @@
   s = stream_new (OSPF_MAX_LSA_SIZE);
   lsah = (struct lsa_header *) STREAM_DATA (s);
 
-  lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA, id);
+  lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
+		  id, area->ospf->router_id);
 
   /* Set summary-LSA body fields. */
   ospf_summary_lsa_body_set (s, p, metric);
@@ -1189,16 +1191,16 @@
   struct ospf_lsa *new;
   struct in_addr id;
   
-  id = ospf_lsa_unique_id (area->lsdb, OSPF_SUMMARY_LSA, p);
+  id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
 
   /* Create new summary-LSA instance. */
   new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id);
 
   /* Instlal LSA to LSDB. */
-  new = ospf_lsa_install (NULL, new);
+  new = ospf_lsa_install (area->ospf, NULL, new);
 
   /* Update LSA origination count. */
-  ospf_top->lsa_originate_count++;
+  area->ospf->lsa_originate_count++;
 
   /* Flooding new LSA through area. */
   ospf_flood_through_area (area, NULL, new);
@@ -1214,7 +1216,7 @@
 }
 
 struct ospf_lsa*
-ospf_summary_lsa_refresh (struct ospf_lsa *lsa)
+ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   struct ospf_lsa *new;
   struct summary_lsa *sl;
@@ -1233,7 +1235,7 @@
   /* Re-calculate checksum. */
   ospf_lsa_checksum (new->data);
 
-  ospf_lsa_install (NULL, new);
+  ospf_lsa_install (ospf, NULL, new);
   
   /* Flood LSA through AS. */
   ospf_flood_through_area (new->area, NULL, new);
@@ -1285,7 +1287,8 @@
   s = stream_new (OSPF_MAX_LSA_SIZE);
   lsah = (struct lsa_header *) STREAM_DATA (s);
 
-  lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA, id);
+  lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
+		  id, area->ospf->router_id);
 
   /* Set summary-LSA body fields. */
   ospf_summary_asbr_lsa_body_set (s, p, metric);
@@ -1315,16 +1318,16 @@
   struct ospf_lsa *new;
   struct in_addr id;
   
-  id = ospf_lsa_unique_id (area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
+  id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
 
   /* Create new summary-LSA instance. */
   new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
 
   /* Install LSA to LSDB. */
-  new = ospf_lsa_install (NULL, new);
+  new = ospf_lsa_install (area->ospf, NULL, new);
   
   /* Update LSA origination count. */
-  ospf_top->lsa_originate_count++;
+  area->ospf->lsa_originate_count++;
 
   /* Flooding new LSA through area. */
   ospf_flood_through_area (area, NULL, new);
@@ -1340,7 +1343,7 @@
 }
 
 struct ospf_lsa*
-ospf_summary_asbr_lsa_refresh (struct ospf_lsa *lsa)
+ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   struct ospf_lsa *new;
   struct summary_lsa *sl;
@@ -1359,7 +1362,7 @@
   /* Re-calculate checksum. */
   ospf_lsa_checksum (new->data);
 
-  ospf_lsa_install (NULL, new);
+  ospf_lsa_install (ospf, NULL, new);
   
   /* Flood LSA through area. */
   ospf_flood_through_area (new->area, NULL, new);
@@ -1379,11 +1382,10 @@
 /* Get nexthop for AS-external-LSAs.  Return nexthop if its interface
    is connected, else 0*/
 struct in_addr
-ospf_external_lsa_nexthop_get (struct in_addr nexthop)
+ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
 {
   struct in_addr fwd;
   struct prefix nh;
-  /* struct route_node *rn; */
   listnode n1;
 
   fwd.s_addr = 0;
@@ -1396,7 +1398,7 @@
   nh.u.prefix4 = nexthop;
   nh.prefixlen = IPV4_MAX_BITLEN;
 
-  for (n1 = listhead (ospf_top->oiflist); n1; nextnode (n1))
+  for (n1 = listhead (ospf->oiflist); n1; nextnode (n1))
     {
       struct ospf_interface *oi = getdata (n1);
 
@@ -1438,24 +1440,26 @@
   fwd.s_addr = 0;
   best_default.s_addr = 0;
 
-
-  for (n1 = listhead (ospf_top->oiflist); n1; nextnode (n1))
+  for (n1 = listhead (area->ospf->oiflist); n1; nextnode (n1))
     {
       struct ospf_interface *oi = getdata (n1);
 
       if (if_is_operative (oi->ifp))
 	if (oi->area->external_routing == OSPF_AREA_NSSA)
-	  if (oi->address && oi->address->family == AF_INET) {
-	    if (best_default.s_addr == 0) {
-	      best_default = oi->address->u.prefix4;
+	  if (oi->address && oi->address->family == AF_INET)
+	    {
+	      if (best_default.s_addr == 0)
+		best_default = oi->address->u.prefix4;
+	      if (oi->area == area)
+		return oi->address->u.prefix4;
 	    }
-	    if (oi->area == area)
-	      return (oi->address->u.prefix4);
-	  }
     }
   if (best_default.s_addr != 0)
     return best_default;
 
+  if (best_default.s_addr != 0)
+    return best_default;
+
   return fwd;
 }
 #endif /* HAVE_NSSA */
@@ -1467,36 +1471,37 @@
 #define DEFAULT_METRIC_TYPE		     EXTERNAL_METRIC_TYPE_2
 
 int
-metric_type (u_char src)
+metric_type (struct ospf *ospf, u_char src)
 {
-  return (ospf_top->dmetric[src].type < 0 ?
-	  DEFAULT_METRIC_TYPE : ospf_top->dmetric[src].type);
+  return (ospf->dmetric[src].type < 0 ?
+	  DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
 }
 
 int
-metric_value (u_char src)
+metric_value (struct ospf *ospf, u_char src)
 {
-  if (ospf_top->dmetric[src].value < 0)
+  if (ospf->dmetric[src].value < 0)
     {
       if (src == DEFAULT_ROUTE)
 	{
-	  if (ospf_top->default_originate == DEFAULT_ORIGINATE_ZEBRA)
+	  if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
 	    return DEFAULT_DEFAULT_ORIGINATE_METRIC;
 	  else
 	    return DEFAULT_DEFAULT_ALWAYS_METRIC;
 	}
-      else if (ospf_top->default_metric < 0)
+      else if (ospf->default_metric < 0)
 	return DEFAULT_DEFAULT_METRIC;
       else
-	return ospf_top->default_metric;
+	return ospf->default_metric;
     }
 
-  return ospf_top->dmetric[src].value;
+  return ospf->dmetric[src].value;
 }
 
 /* Set AS-external-LSA body. */
 void
-ospf_external_lsa_body_set (struct stream *s, struct external_info *ei)
+ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
+			    struct ospf *ospf)
 {
   struct prefix_ipv4 *p = &ei->p;
   struct in_addr mask, fwd_addr;
@@ -1512,10 +1517,10 @@
   type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
   
   mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
-    ROUTEMAP_METRIC_TYPE (ei) : metric_type (type);
+    ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
 
   mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
-    ROUTEMAP_METRIC (ei) : metric_value (type);
+    ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
 
   /* Put type of external metric. */
   stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
@@ -1524,7 +1529,7 @@
   stream_put_ospf_metric (s, mvalue);
   
   /* Get forwarding address to nexthop if on the Connection List, else 0. */
-  fwd_addr = ospf_external_lsa_nexthop_get (ei->nexthop);
+  fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
 
   /* Put forwarding address. */
   stream_put_ipv4 (s, fwd_addr.s_addr);
@@ -1535,7 +1540,8 @@
 
 /* Create new external-LSA. */
 struct ospf_lsa *
-ospf_external_lsa_new (struct external_info *ei, struct in_addr *old_id)
+ospf_external_lsa_new (struct ospf *ospf,
+		       struct external_info *ei, struct in_addr *old_id)
 {
   struct stream *s;
   struct lsa_header *lsah;
@@ -1559,7 +1565,7 @@
   /* Get Link State with unique ID. */
   else
     {
-      id = ospf_lsa_unique_id (ospf_top->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
+      id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
       if (id.s_addr == 0xffffffff)
 	{
 	  /* Maybe Link State ID not available. */
@@ -1574,10 +1580,11 @@
   lsah = (struct lsa_header *) STREAM_DATA (s);
 
   /* Set LSA common header fields. */
-  lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA, id);
+  lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
+		  id, ospf->router_id);
 
   /* Set AS-external-LSA body fields. */
-  ospf_external_lsa_body_set (s, ei);
+  ospf_external_lsa_body_set (s, ei, ospf);
 
   /* Set length. */
   length = stream_get_endp (s);
@@ -1597,56 +1604,13 @@
 }
 
 #ifdef HAVE_NSSA
-/* Set AS-external-LSA body test. */
-void
-ospf_external_lsa_body_test (struct stream *s)
-{
-  struct in_addr mask, fwd_addr;
-  u_int32_t mvalue = 0;
-  /* int mtype;
-     int type; */
-
-  mask.s_addr = 0;
-  fwd_addr.s_addr = 0;
-
-  /* Put Network Mask. */
-  /* masklen2ip (p->prefixlen, &mask); */
-  stream_put_ipv4 (s, mask.s_addr);
-
-  /* If prefix is default, specify DEFAULT_ROUTE. */
-  /* type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
-  
-  mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
-  ROUTEMAP_METRIC_TYPE (ei) : metric_type (type);
-
-  mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
-  ROUTEMAP_METRIC (ei) : metric_value (type); */
-
-  /* Put type of external metric. */
-  stream_putc (s,  0);
-
-  /* Put 0 metric. TOS metric is not supported. */
-  stream_put_ospf_metric (s, mvalue);
-  
- 
-  /*  fwd_addr = ospf_top->router_id; */
-       
-  /* OLD == ospf_external_lsa_nexthop_get (ei->nexthop); */
-
-  /* Put forwarding address. */
-  /* stream_put_ipv4 (s, fwd_addr.s_addr); */
-  stream_put_ipv4 (s, ospf_top->router_id.s_addr);
-  
-  /* Put route tag -- This value should be introduced from configuration. */
-  stream_putl (s, 0);
-}
-
 /* As Type-7 */
 void
-ospf_install_flood_nssa (struct ospf_lsa *lsa, struct external_info *ei)
+ospf_install_flood_nssa (struct ospf *ospf, 
+			 struct ospf_lsa *lsa, struct external_info *ei)
 {
   struct ospf_lsa *new2;
-  struct as_external_lsa *extlsa, *newextlsa;
+  struct as_external_lsa *extlsa;
   listnode node;
 
   /* NSSA Originate or Refresh (If anyNSSA)
@@ -1664,65 +1628,58 @@
   Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
   Type-5's to non-NSSA Areas.  (it will also attempt a re-install) */
 
-  for (node = listhead (ospf_top->areas); node; nextnode (node)) {
-  
-  	  struct ospf_area *area = getdata (node);
+  for (node = listhead (ospf->areas); node; nextnode (node))
+    {
+      struct ospf_area *area = getdata (node);
 
-	  /* make lsa duplicate, lock=1 */
-	  new2 = ospf_lsa_dup(lsa);
+      /* make lsa duplicate, lock=1 */
+      new2 = ospf_lsa_dup (lsa);
+      new2->area = area;
+      new2->data->type = OSPF_AS_NSSA_LSA;
 
-	  /* make type-7 */
-	  new2->data->type  = OSPF_AS_NSSA_LSA;
+      /* set P-bit if not ABR */
+      if (! OSPF_IS_ABR)
+        {
+	  SET_FLAG(new2->data->options, OSPF_OPTION_NP);
+       
+	  /* set non-zero FWD ADDR
+       
+	  draft-ietf-ospf-nssa-update-09.txt
+       
+	  if the network between the NSSA AS boundary router and the
+	  adjacent AS is advertised into OSPF as an internal OSPF route,
+	  the forwarding address should be the next op address as is cu
+	  currently done with type-5 LSAs.  If the intervening network is
+	  not adversited into OSPF as an internal OSPF route and the
+	  type-7 LSA's P-bit is set a forwarding address should be
+	  selected from one of the router's active OSPF inteface addresses
+	  which belong to the NSSA.  If no such addresses exist, then
+	  no type-7 LSA's with the P-bit set should originate from this
+	  router.   */
+       
+	  /* kevinm: not updating lsa anymore, just new2 */
+	  extlsa = (struct as_external_lsa *)(new2->data);
+       
+	  if (extlsa->e[0].fwd_addr.s_addr == 0)
+	    extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
 
-	  /* set P-bit if not ABR */
-	  if (! OSPF_IS_ABR)
-	    {
-	      SET_FLAG(new2->data->options, OSPF_OPTION_NP);
-
-	      /* set non-zero FWD ADDR 
-
-	      draft-ietf-ospf-nssa-update-09.txt
-
-	      if the network between the NSSA AS boundary router and the
-	      adjacent AS is advertised into OSPF as an internal OSPF route, 
-	      the forwarding address should be the next op address as is cu
-	      currently done with type-5 LSAs.  If the intervening network is 
-	      not adversited into OSPF as an internal OSPF route and the 
-	      type-7 LSA's P-bit is set a forwarding address should be 
-	      selected from one of the router's active OSPF inteface addresses
-	      which belong to the NSSA.  If no such addresses exist, then
-	      no type-7 LSA's with the P-bit set should originate from this
-	      router.   */
-
-		/* not updating lsa anymore, just new2 */ 
-		extlsa = (struct as_external_lsa *)(new2->data);
-
-	      if (extlsa->e[0].fwd_addr.s_addr == 0) 
-		/* this NSSA area in ifp */
-		extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); 
-
-	      if (IS_DEBUG_OSPF_NSSA)
-		if (extlsa->e[0].fwd_addr.s_addr == 0) 
-		  {
-		    zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
-		    ospf_lsa_discard(new2);
-		    return;
-		  }
-	    }
-
-	  /* Re-calculate checksum. */
-	  ospf_lsa_checksum (new2->data);
-
-	  /* install also as Type-7 */
-	  ospf_lsa_install (NULL, new2);   /* Remove Old, Lock New = 2 */
-
-	  /* will send each copy, lock=2+n */
-	  ospf_flood_through_as (NULL, new2); /* all attached NSSA's, no AS/STUBs */
+	  if (IS_DEBUG_OSPF_NSSA)
+	    if (extlsa->e[0].fwd_addr.s_addr == 0) 
+	      {
+		zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
+		ospf_lsa_discard(new2);
+		return;
+	      }
 	}
+      /* Re-calculate checksum. */
+      ospf_lsa_checksum (new2->data);
 
-  /* last send, lock=2 LSA is now permanent in Type-7 LSDB */
-  /* It has the same ID as it's Type-5 Counter-Part */
- 
+      /* install also as Type-7 */
+      ospf_lsa_install (ospf, NULL, new2);   /* Remove Old, Lock New = 2 */
+
+      /* will send each copy, lock=2+n */
+      ospf_flood_through_as (ospf, NULL, new2); /* all attached NSSA's, no AS/STUBs */
+    }
 }
 #endif /* HAVE_NSSA */
 
@@ -1740,7 +1697,7 @@
 
 /* Originate an AS-external-LSA, install and flood. */
 struct ospf_lsa *
-ospf_external_lsa_originate (struct external_info *ei)
+ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
 {
   struct ospf_lsa *new;
 
@@ -1780,11 +1737,11 @@
      */
   
   /* Check the AS-external-LSA should be originated. */
-  if (!ospf_redistribute_check (ei, NULL))
+  if (!ospf_redistribute_check (ospf, ei, NULL))
     return NULL;
   
   /* Create new AS-external-LSA instance. */
-  if ((new = ospf_external_lsa_new (ei, NULL)) == NULL)
+  if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
     {
       if (IS_DEBUG_OSPF_EVENT)
 	zlog_info ("LSA[Type5:%s]: Could not originate AS-external-LSA",
@@ -1793,18 +1750,18 @@
     }
 
   /* Install newly created LSA into Type-5 LSDB, lock = 1. */
-  ospf_lsa_install (NULL, new);
+  ospf_lsa_install (ospf, NULL, new);
 
   /* Update LSA origination count. */
-  ospf_top->lsa_originate_count++;
+  ospf->lsa_originate_count++;
 
   /* Flooding new LSA. only to AS (non-NSSA/STUB) */
-  ospf_flood_through_as (NULL, new);
+  ospf_flood_through_as (ospf, NULL, new);
 
 #ifdef HAVE_NSSA
   /* If there is any attached NSSA, do special handling */
-  if (ospf_top->anyNSSA)
-    ospf_install_flood_nssa (new, ei); /* Install/Flood Type-7 to all NSSAs */
+  if (ospf->anyNSSA)
+    ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
 #endif /* HAVE_NSSA */
 
   /* Debug logging. */
@@ -1820,22 +1777,22 @@
 
 /* Originate AS-external-LSA from external info with initial flag. */
 int
-ospf_external_lsa_originate_timer (struct thread *t)
+ospf_external_lsa_originate_timer (struct thread *thread)
 {
+  struct ospf *ospf = THREAD_ARG (thread);
   struct route_node *rn;
   struct external_info *ei;
   struct route_table *rt;
-  int type;
+  int type = THREAD_VAL (thread);
 
-  ospf_top->t_external_lsa = NULL;
-  type = THREAD_VAL (t);
+  ospf->t_external_lsa = NULL;
 
   /* Originate As-external-LSA from all type of distribute source. */
   if ((rt = EXTERNAL_INFO (type)))
     for (rn = route_top (rt); rn; rn = route_next (rn))
       if ((ei = rn->info) != NULL)
 	if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
-	  if (!ospf_external_lsa_originate (ei))
+	  if (!ospf_external_lsa_originate (ospf, ei))
 	    zlog_warn ("LSA: AS-external-LSA was not originated.");
   
   return 0;
@@ -1847,6 +1804,7 @@
   int type;
   struct route_node *rn;
   struct prefix_ipv4 p;
+  struct ospf *ospf = ospf_top;
   
   p.family = AF_INET;
   p.prefix.s_addr = 0;
@@ -1861,7 +1819,7 @@
 	  {
 	    route_unlock_node (rn);
 	    assert (rn->info);
-	    if (ospf_redistribute_check (rn->info, NULL))
+	    if (ospf_redistribute_check (ospf, rn->info, NULL))
 	      return rn->info;
 	  }
       }
@@ -1870,15 +1828,16 @@
 }
 
 int
-ospf_default_originate_timer (struct thread *t)
+ospf_default_originate_timer (struct thread *thread)
 {
   int *origin;
   struct prefix_ipv4 p;
   struct in_addr nexthop;
   struct external_info *ei;
+  struct ospf *ospf = ospf_top;
   
   /* Get originate flags. */
-  origin = THREAD_ARG (t);
+  origin = THREAD_ARG (thread);
 
   p.family = AF_INET;
   p.prefix.s_addr = 0;
@@ -1893,14 +1852,15 @@
     }
 
   if ((ei = ospf_default_external_info ()))
-    ospf_external_lsa_originate (ei);
+    ospf_external_lsa_originate (ospf, ei);
   
   return 0;
 }
 
 /* Flush an AS-external-LSA from LSDB and routing domain. */
 void
-ospf_external_lsa_flush (u_char type, struct prefix_ipv4 *p,
+ospf_external_lsa_flush (struct ospf *ospf,
+			 u_char type, struct prefix_ipv4 *p,
 			 unsigned int ifindex, struct in_addr nexthop)
 {
   struct ospf_lsa *lsa;
@@ -1910,7 +1870,7 @@
 	       inet_ntoa (p->prefix), p->prefixlen);
 
   /* First lookup LSA from LSDB. */
-  if (!(lsa = ospf_external_info_find_lsa (p)))
+  if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
     {
       if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
 	zlog_warn ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
@@ -1919,7 +1879,7 @@
     }
 
   /* Sweep LSA from Link State Retransmit List. */
-  ospf_ls_retransmit_delete_nbr_all (NULL, lsa);
+  ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
 
   /* There must be no self-originated LSA in rtrs_external. */
 #if 0
@@ -1930,10 +1890,10 @@
   if (!IS_LSA_MAXAGE (lsa))
     {
       /* Unregister LSA from Refresh queue. */
-      ospf_refresher_unregister_lsa (ospf_top, lsa);
+      ospf_refresher_unregister_lsa (ospf, lsa);
 
       /* Flush AS-external-LSA through AS. */
-      ospf_flush_through_as (lsa);
+      ospf_lsa_flush_as (ospf, lsa);
     }
 
   if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
@@ -1941,7 +1901,7 @@
 }
 
 void
-ospf_external_lsa_refresh_default ()
+ospf_external_lsa_refresh_default (struct ospf *ospf)
 {
   struct prefix_ipv4 p;
   struct external_info *ei;
@@ -1952,7 +1912,7 @@
   p.prefix.s_addr = 0;
 
   ei = ospf_default_external_info ();
-  lsa = ospf_external_info_find_lsa (&p);
+  lsa = ospf_external_info_find_lsa (ospf, &p);
 
   if (ei)
     {
@@ -1960,13 +1920,13 @@
 	{
 	  if (IS_DEBUG_OSPF_EVENT)
 	    zlog_info ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
-	  ospf_external_lsa_refresh (lsa, ei, LSA_REFRESH_FORCE);
+	  ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
 	}
       else
 	{
 	  if (IS_DEBUG_OSPF_EVENT)
 	    zlog_info ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
-	  ospf_external_lsa_originate (ei);
+	  ospf_external_lsa_originate (ospf, ei);
 	}
     }
   else
@@ -1975,13 +1935,13 @@
 	{
 	  if (IS_DEBUG_OSPF_EVENT)
 	    zlog_info ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
-	  ospf_lsa_flush_as (lsa);
+	  ospf_lsa_flush_as (ospf, lsa);
 	}
     }
 }
 
 void
-ospf_external_lsa_refresh_type (u_char type, int force)
+ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
 {
   struct route_node *rn;
   struct external_info *ei;
@@ -1995,25 +1955,26 @@
 	    {
 	      struct ospf_lsa *lsa;
 
-	      if ((lsa = ospf_external_info_find_lsa (&ei->p)))
-		ospf_external_lsa_refresh (lsa, ei, force);
+	      if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
+		ospf_external_lsa_refresh (ospf, lsa, ei, force);
 	      else
-		ospf_external_lsa_originate (ei);
+		ospf_external_lsa_originate (ospf, ei);
 	    }
 }
 
 /* Refresh AS-external-LSA. */
 void
-ospf_external_lsa_refresh (struct ospf_lsa *lsa,
+ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
 			   struct external_info *ei, int force)
 {
   struct ospf_lsa *new;
   int changed;
   
   /* Check the AS-external-LSA should be originated. */
-  if (!ospf_redistribute_check (ei, &changed))
+  if (!ospf_redistribute_check (ospf, ei, &changed))
     {
-      ospf_external_lsa_flush (ei->type, &ei->p, ei->ifindex, ei->nexthop);
+      ospf_external_lsa_flush (ospf, ei->type, &ei->p,
+			       ei->ifindex, ei->nexthop);
       return;
     }
 
@@ -2021,12 +1982,12 @@
     return;
 
   /* Delete LSA from neighbor retransmit-list. */
-  ospf_ls_retransmit_delete_nbr_all (NULL, lsa);
+  ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
 
   /* Unregister AS-external-LSA from refresh-list. */
-  ospf_refresher_unregister_lsa (ospf_top, lsa);
+  ospf_refresher_unregister_lsa (ospf, lsa);
 
-  new = ospf_external_lsa_new (ei, &lsa->data->id);
+  new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
   
   if (new == NULL)
     {
@@ -2044,19 +2005,19 @@
   /* Re-calculate checksum. */
   ospf_lsa_checksum (new->data);
 
-  ospf_lsa_install (NULL, new);	/* As type-5. */
+  ospf_lsa_install (ospf, NULL, new);	/* As type-5. */
 
   /* Flood LSA through AS. */
-  ospf_flood_through_as (NULL, new);
+  ospf_flood_through_as (ospf, NULL, new);
 
 #ifdef HAVE_NSSA
   /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
-  if (ospf_top->anyNSSA)
-    ospf_install_flood_nssa (new, ei); /* Install/Flood per new rules */
+  if (ospf->anyNSSA)
+    ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
 #endif /* HAVE_NSSA */
 
   /* Register slef-originated LSA to refresh queue. */
-  ospf_refresher_register_lsa (ospf_top, new);
+  ospf_refresher_register_lsa (ospf, new);
 
   /* Debug logging. */
   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
@@ -2074,7 +2035,8 @@
 
 /* Install router-LSA to an area. */
 struct ospf_lsa *
-ospf_router_lsa_install (struct ospf_lsa *new, int rt_recalc)
+ospf_router_lsa_install (struct ospf *ospf,
+			 struct ospf_lsa *new, int rt_recalc)
 {
   struct ospf_area *area = new->area;
 
@@ -2084,7 +2046,7 @@
      area whose link-state database has changed). 
   */
   if (rt_recalc)
-    ospf_spf_calculate_schedule();
+    ospf_spf_calculate_schedule (ospf);
 
   if (IS_LSA_SELF (new))
     {
@@ -2111,7 +2073,8 @@
 
 /* Install network-LSA to an area. */
 struct ospf_lsa *
-ospf_network_lsa_install (struct ospf_interface *oi, 
+ospf_network_lsa_install (struct ospf *ospf,
+			  struct ospf_interface *oi, 
 			  struct ospf_lsa *new,
 			  int rt_recalc)
 {
@@ -2122,7 +2085,7 @@
      area whose link-state database has changed). 
   */
   if (rt_recalc)
-    ospf_spf_calculate_schedule();
+    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,
@@ -2145,9 +2108,9 @@
 
 /* Install summary-LSA to an area. */
 struct ospf_lsa *
-ospf_summary_lsa_install (struct ospf_lsa *new, int rt_recalc)
+ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
+			  int rt_recalc)
 {
-
   if (rt_recalc && !IS_LSA_SELF (new))
     {
       /* RFC 2328 Section 13.2 Summary-LSAs
@@ -2161,7 +2124,7 @@
       /* This doesn't exist yet... */
       ospf_summary_incremental_update(new); */
 #else /* #if 0 */
-      ospf_spf_calculate_schedule();
+      ospf_spf_calculate_schedule (ospf);
 #endif /* #if 0 */
  
       if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
@@ -2169,14 +2132,15 @@
     }
 
   if (IS_LSA_SELF (new))
-    ospf_refresher_register_lsa (ospf_top, new);
+    ospf_refresher_register_lsa (ospf, new);
 
   return new;
 }
 
 /* Install ASBR-summary-LSA to an area. */
 struct ospf_lsa *
-ospf_summary_asbr_lsa_install (struct ospf_lsa *new, int rt_recalc)
+ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
+			       int rt_recalc)
 {
   if (rt_recalc && !IS_LSA_SELF (new))
     {
@@ -2193,22 +2157,23 @@
 	 - RFC 2328 Section 16.5 implies it should be */
       /* ospf_ase_calculate_schedule(); */
 #else  /* #if 0 */
-      ospf_spf_calculate_schedule();
+      ospf_spf_calculate_schedule (ospf);
 #endif /* #if 0 */
     }
 
   /* register LSA to refresh-list. */
   if (IS_LSA_SELF (new))
-    ospf_refresher_register_lsa (ospf_top, new);
+    ospf_refresher_register_lsa (ospf, new);
 
   return new;
 }
 
 /* Install AS-external-LSA. */
 struct ospf_lsa *
-ospf_external_lsa_install (struct ospf_lsa *new, int rt_recalc)
+ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
+			   int rt_recalc)
 {
-  ospf_ase_register_external_lsa (new, ospf_top);
+  ospf_ase_register_external_lsa (new, ospf);
   /* If LSA is not self-originated, calculate an external route. */
   if (rt_recalc)
     {
@@ -2218,18 +2183,19 @@
       */
 
       if (!IS_LSA_SELF (new))
-	ospf_ase_incremental_update (new, ospf_top);
+	ospf_ase_incremental_update (ospf, new);
     }
 
   /* Register self-originated LSA to refresh queue. */
   if (IS_LSA_SELF (new))
-    ospf_refresher_register_lsa (ospf_top, new);
+    ospf_refresher_register_lsa (ospf, new);
 
   return new;
 }
 
 void
-ospf_discard_from_db (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
+ospf_discard_from_db (struct ospf *ospf,
+		      struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
 {
   struct ospf_lsa *old;
   
@@ -2239,9 +2205,7 @@
     return;
 
   if (old->refresh_list >= 0)
-    ospf_refresher_unregister_lsa (ospf_top, old);
-
-  ospf_ls_retransmit_delete_nbr_all (old->area, old);
+    ospf_refresher_unregister_lsa (ospf, old);
 
   switch (old->data->type)
     {
@@ -2249,31 +2213,21 @@
 #ifdef HAVE_OPAQUE_LSA
     case OSPF_OPAQUE_AS_LSA:
 #endif /* HAVE_OPAQUE_LSA */
-      ospf_ase_unregister_external_lsa (old, ospf_top);
+      ospf_ls_retransmit_delete_nbr_as (ospf, old);
+      ospf_ase_unregister_external_lsa (old, ospf);
       break;
     default:
+      ospf_ls_retransmit_delete_nbr_area (old->area, old);
       break;
     }
 
-  ospf_lsa_maxage_delete (old);
+  ospf_lsa_maxage_delete (ospf, old);
   ospf_lsa_discard (old);
 }
 
-/* callback for foreach_lsa */
-int
-ospf_lsa_discard_callback (struct ospf_lsa *lsa, void *p, int i)
-{
-#ifdef HAVE_NSSA
-  /* Removed: Stay away from any Local Translated Type-7 LSAs */
-  /* if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
-     return 0; */
-#endif /* HAVE_NSSA */
-  ospf_discard_from_db ((struct ospf_lsdb *)p, lsa);
-  return 0;
-}
-
 struct ospf_lsa *
-ospf_lsa_install (struct ospf_interface *oi, struct ospf_lsa *lsa)
+ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
+		  struct ospf_lsa *lsa)
 {
   struct ospf_lsa *new = NULL;
   struct ospf_lsa *old = NULL;
@@ -2283,34 +2237,26 @@
   /* Set LSDB. */
   switch (lsa->data->type)
     {
+#ifdef HAVE_NSSA
       /* kevinm */
     case OSPF_AS_NSSA_LSA:
       if (lsa->area)
 	lsdb = lsa->area->lsdb;
       else
-	lsdb = ospf_top->lsdb;
+	lsdb = ospf->lsdb;
       break;
+#endif /* HAVE_NSSA */
     case OSPF_AS_EXTERNAL_LSA:
 #ifdef HAVE_OPAQUE_LSA
     case OSPF_OPAQUE_AS_LSA:
 #endif /* HAVE_OPAQUE_LSA */
-      lsdb = ospf_top->lsdb;
+      lsdb = ospf->lsdb;
       break;
     default:
       lsdb = lsa->area->lsdb;
       break;
     }
 
-#ifdef HAVE_NSSA
-  if (IS_DEBUG_OSPF_NSSA)
-    {
-      zlog_info ("LSA[Installing]: Type-%d ", lsa->data->type);
-
-      if  (lsa->data->type == OSPF_AS_NSSA_LSA )
-	zlog_info ("NSSA LSA AREA = %s", inet_ntoa (lsa->area->area_id));
-    }
-#endif /* HAVE_NSSA */
-
   assert (lsdb);
 
   /*  RFC 2328 13.2.  Installing LSAs in the database
@@ -2346,7 +2292,7 @@
 
   /* discard old LSA from LSDB */
   if (old != NULL)
-    ospf_discard_from_db (lsdb, lsa);
+    ospf_discard_from_db (ospf, lsdb, lsa);
 
   /* Insert LSA to LSDB. */
   ospf_lsdb_add (lsdb, lsa);
@@ -2360,27 +2306,27 @@
   switch (lsa->data->type)
     {
     case OSPF_ROUTER_LSA:
-      new = ospf_router_lsa_install (lsa, rt_recalc);
+      new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
       break;
     case OSPF_NETWORK_LSA:
       assert (oi);
-      new = ospf_network_lsa_install (oi, lsa, rt_recalc);
+      new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
       break;
     case OSPF_SUMMARY_LSA:
-      new = ospf_summary_lsa_install (lsa, rt_recalc);
+      new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
       break;
     case OSPF_ASBR_SUMMARY_LSA:
-      new = ospf_summary_asbr_lsa_install (lsa, rt_recalc);
+      new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
       break;
     case OSPF_AS_EXTERNAL_LSA:
-      new = ospf_external_lsa_install (lsa, rt_recalc);
+      new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
       break;
 #ifdef HAVE_OPAQUE_LSA
     case OSPF_OPAQUE_LINK_LSA:
       if (IS_LSA_SELF (lsa))
-          lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
+	lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
       else
-          ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
+	; /* Incoming "oi" for this LSA has set at LSUpd reception. */
       /* Fallthrough */
     case OSPF_OPAQUE_AREA_LSA:
     case OSPF_OPAQUE_AS_LSA:
@@ -2389,7 +2335,7 @@
 #endif /* HAVE_OPAQUE_LSA */
     default: /* NSSA, or type-6,8,9....nothing special */
 #ifdef HAVE_NSSA
-      new = ospf_external_lsa_install (lsa, rt_recalc);
+      new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
 #endif /* HAVE_NSSA */
       break;
     }
@@ -2410,7 +2356,7 @@
 #endif /* HAVE_OPAQUE_LSA */
 #ifdef HAVE_NSSA
 	case OSPF_AS_NSSA_LSA:
-#endif
+#endif /* HAVE_NSSA */
           zlog_info ("LSA[%s]: Install %s",
                  dump_lsa_key (new),
                  LOOKUP (ospf_lsa_type_msg, new->data->type));
@@ -2430,7 +2376,7 @@
       if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
 	zlog_info ("LSA[Type%d:%s]: Install LSA, MaxAge",
 		   new->data->type, inet_ntoa (new->data->id));
-      ospf_lsa_maxage (lsa);
+      ospf_lsa_maxage (ospf, lsa);
     }
 
   return new;
@@ -2438,11 +2384,11 @@
 
 
 int
-ospf_check_nbr_status ()
+ospf_check_nbr_status (struct ospf *ospf)
 {
   listnode node;
 
-  for (node = listhead (ospf_top->oiflist); node; node = nextnode (node))
+  for (node = listhead (ospf->oiflist); node; node = nextnode (node))
     {
       struct ospf_interface *oi = getdata (node);
       struct route_node *rn;
@@ -2497,19 +2443,20 @@
 int
 ospf_maxage_lsa_remover (struct thread *thread)
 {
+  struct ospf *ospf = THREAD_ARG (thread);
   listnode node;
   listnode next;
   int reschedule = 0;
 
-  ospf_top->t_maxage = NULL;
+  ospf->t_maxage = NULL;
 
   if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
     zlog_info ("LSA[MaxAge]: remover Start");
 
-  reschedule = !ospf_check_nbr_status ();
+  reschedule = !ospf_check_nbr_status (ospf);
 
   if (!reschedule)
-    for (node = listhead (ospf_top->maxage_lsa); node; node = next)
+    for (node = listhead (ospf->maxage_lsa); node; node = next)
       {
         struct ospf_lsa *lsa = getdata (node);
         next = node->next;
@@ -2534,11 +2481,11 @@
 #ifdef ORIGINAL_CODING
 	ospf_maxage_flood (lsa);
 #else /* ORIGINAL_CODING */
-        ospf_flood_through (NULL, lsa);
+        ospf_flood_through (ospf, NULL, lsa);
 #endif /* ORIGINAL_CODING */
 
 	/* Remove from lsdb. */
-        ospf_discard_from_db (lsa->lsdb, lsa);
+        ospf_discard_from_db (ospf, lsa->lsdb, lsa);
         ospf_lsdb_delete (lsa->lsdb, lsa);
       }
 
@@ -2547,17 +2494,17 @@
         neighbor Link state retransmission lists and b) none of the router's
         neighbors are in states Exchange or Loading. */
   if (reschedule)
-    OSPF_SCHEDULE_MAXAGE (ospf_top->t_maxage, ospf_maxage_lsa_remover);
+    OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
 
   return 0;
 }
 
 int
-ospf_lsa_maxage_exist (struct ospf_lsa *new)
+ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
 {
   listnode node;
 
-  for (node = listhead (ospf_top->maxage_lsa); node; nextnode (node))
+  for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
     if (((struct ospf_lsa *) node->data) == new)
       return 1;
 
@@ -2565,23 +2512,23 @@
 }
 
 void
-ospf_lsa_maxage_delete (struct ospf_lsa *lsa)
+ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   listnode n;
 
-  if ((n = listnode_lookup (ospf_top->maxage_lsa, lsa)))
+  if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
     {
-      list_delete_node (ospf_top->maxage_lsa, n);
+      list_delete_node (ospf->maxage_lsa, n);
       ospf_lsa_unlock (lsa);
     }
 }
 
 void
-ospf_lsa_maxage (struct ospf_lsa *lsa)
+ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   /* When we saw a MaxAge LSA flooded to us, we put it on the list
      and schedule the MaxAge LSA remover. */
-  if (ospf_lsa_maxage_exist (lsa))
+  if (ospf_lsa_maxage_exist (ospf, lsa))
     {
       if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
 	zlog_info ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
@@ -2589,16 +2536,16 @@
       return;
     }
 
-  listnode_add (ospf_top->maxage_lsa, ospf_lsa_lock (lsa));
+  listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
 
   if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
     zlog_info ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
 
-  OSPF_SCHEDULE_MAXAGE (ospf_top->t_maxage, ospf_maxage_lsa_remover);
+  OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
 }
 
 int
-ospf_lsa_maxage_walker_remover (struct ospf_lsa *lsa, void *p_arg, int int_arg)
+ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
 {
 #ifdef HAVE_NSSA
   /* Stay away from any Local Translated Type-7 LSAs */
@@ -2609,7 +2556,7 @@
   if (IS_LSA_MAXAGE (lsa))
     /* Self-originated LSAs should NOT time-out instead,
        they're flushed and submitted to the max_age list explicitly. */
-    if (!ospf_lsa_is_self_originated (lsa))
+    if (!ospf_lsa_is_self_originated (ospf, lsa))
       {
 	if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
 	  zlog_info("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
@@ -2630,18 +2577,17 @@
              */
             break;
 #endif /* HAVE_OPAQUE_LSA */
-#ifdef HAVE_NSSA
-	      case OSPF_AS_NSSA_LSA:
-#endif
           case OSPF_AS_EXTERNAL_LSA:
-	       ospf_ase_incremental_update (lsa, ospf_top);
-           break;
+#ifdef HAVE_NSSA
+	  case OSPF_AS_NSSA_LSA:
+#endif /* HAVE_NSSA */
+	    ospf_ase_incremental_update (ospf, lsa);
+            break;
           default:
-	       ospf_spf_calculate_schedule ();
-           break;
+	    ospf_spf_calculate_schedule (ospf);
+            break;
           }
-
-	   ospf_lsa_maxage (lsa);
+	ospf_lsa_maxage (ospf, lsa);
       }
 
   return 0;
@@ -2649,90 +2595,80 @@
 
 /* Periodical check of MaxAge LSA. */
 int
-ospf_lsa_maxage_walker (struct thread *t)
+ospf_lsa_maxage_walker (struct thread *thread)
 {
+  struct ospf *ospf = THREAD_ARG (thread);
+  struct route_node *rn;
+  struct ospf_lsa *lsa;
   listnode node;
 
-  ospf_top->t_maxage_walker = NULL;
+  ospf->t_maxage_walker = NULL;
 
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     {
       struct ospf_area *area = node->data;
 
-      foreach_lsa (ROUTER_LSDB (area), NULL, 0,
-		   ospf_lsa_maxage_walker_remover);
-      foreach_lsa (NETWORK_LSDB (area), NULL, 0,
-		   ospf_lsa_maxage_walker_remover);
-      foreach_lsa (SUMMARY_LSDB (area), NULL, 0,
-		   ospf_lsa_maxage_walker_remover);
-      foreach_lsa (ASBR_SUMMARY_LSDB (area), NULL, 0,
-		   ospf_lsa_maxage_walker_remover);
+      LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
+	ospf_lsa_maxage_walker_remover (ospf, lsa);
+      LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
+	ospf_lsa_maxage_walker_remover (ospf, lsa);
+      LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
+	ospf_lsa_maxage_walker_remover (ospf, lsa);
+      LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
+	ospf_lsa_maxage_walker_remover (ospf, lsa);
 #ifdef HAVE_OPAQUE_LSA
-      foreach_lsa (OPAQUE_LINK_LSDB (area), NULL, 0,
-		   ospf_lsa_maxage_walker_remover);
-      foreach_lsa (OPAQUE_AREA_LSDB (area), NULL, 0,
-		   ospf_lsa_maxage_walker_remover);
+      LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
+	ospf_lsa_maxage_walker_remover (ospf, lsa);
+      LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
+	ospf_lsa_maxage_walker_remover (ospf, lsa);
 #endif /* HAVE_OPAQUE_LSA */
     }
 
   /* for AS-eternal-LSAs. */
-  if (ospf_top->lsdb)
-    foreach_lsa (EXTERNAL_LSDB (ospf_top), NULL, 0,
-		 ospf_lsa_maxage_walker_remover);
-
+  if (ospf->lsdb)
+    {
+      LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
+	ospf_lsa_maxage_walker_remover (ospf, lsa);
 #ifdef HAVE_OPAQUE_LSA
-  if (ospf_top->lsdb)
-    foreach_lsa (OPAQUE_AS_LSDB (ospf_top), NULL, 0,
-		 ospf_lsa_maxage_walker_remover);
+      LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
+	ospf_lsa_maxage_walker_remover (ospf, lsa);
 #endif /* HAVE_OPAQUE_LSA */
+    }
 
-  ospf_top->t_maxage_walker = 
-    thread_add_timer (master, ospf_lsa_maxage_walker, NULL,
-                      OSPF_LSA_MAXAGE_CHECK_INTERVAL);
+  OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
+		 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
   return 0;
 }
 
-int
-find_summary (struct ospf_lsa *lsa, void * v, int i)
+struct ospf_lsa *
+ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
+			   struct prefix_ipv4 *p, struct in_addr router_id)
 {
-  struct prefix_ipv4 *p, pr;
+  struct ospf_lsa *lsa;
+  struct in_addr mask, id;
+  struct lsa_header_mask
+  {
+    struct lsa_header header;
+    struct in_addr mask;
+  } *hmask;
 
-  if ((p = (struct prefix_ipv4 *) v) != NULL)
-    if (lsa != NULL)
-      /* We're looking for self-originated one */
-      if (ospf_lsa_is_self_originated (lsa))
-	{
-	  struct summary_lsa *sl = (struct summary_lsa *) lsa->data;
+  lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
+  if (lsa == NULL)
+    return NULL;
 
-	  pr.family = AF_INET;
-	  pr.prefix = sl->header.id;
-	  pr.prefixlen = ip_masklen (sl->mask);
-	  apply_mask_ipv4 (&pr);
+  masklen2ip (p->prefixlen, &mask);
 
-	  if (prefix_same ((struct prefix*) &pr, (struct prefix*) p))
-	    return 1;
-	}
+  hmask = (struct lsa_header_mask *) lsa->data;
 
-  return 0;
-}
+  if (mask.s_addr != hmask->mask.s_addr)
+    {
+      id.s_addr = p->prefix.s_addr | (~mask.s_addr);
+      lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
+      if (!lsa)
+        return NULL;
+    }
 
-int
-find_asbr_summary (struct ospf_lsa *lsa, void * v, int i)
-{
-  struct prefix_ipv4 *p;
-
-  if ((p = (struct prefix_ipv4 *) v) != NULL)
-    if (lsa != NULL)
-      /* We're looking for self-originated one */
-      if (ospf_lsa_is_self_originated (lsa))
-	{
-	  struct summary_lsa *sl = (struct summary_lsa *) lsa->data;
-
-	  if (IPV4_ADDR_SAME (&p->prefix, &sl->header.id))
-	    return 1;
-	}
-
-  return 0;
+  return lsa;
 }
 
 struct ospf_lsa *
@@ -2956,7 +2892,7 @@
 }
 #else /* ORIGINAL_CODING */
 static int
-ospf_lsa_flush_schedule (struct ospf_lsa *lsa, void *v, int i)
+ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   if (lsa == NULL || !IS_LSA_SELF (lsa))
     return 0;
@@ -2977,7 +2913,7 @@
       break;
 #endif /* HAVE_OPAQUE_LSA */
     default:
-      ospf_lsa_maxage (lsa);
+      ospf_lsa_maxage (ospf, lsa);
       break;
     }
 
@@ -2985,15 +2921,16 @@
 }
 
 void
-ospf_flush_self_originated_lsas_now (struct ospf *top)
+ospf_flush_self_originated_lsas_now (struct ospf *ospf)
 {
   listnode n1, n2;
   struct ospf_area *area;
   struct ospf_interface *oi;
   struct ospf_lsa *lsa;
+  struct route_node *rn;
   int need_to_flush_ase = 0;
 
-  for (n1 = listhead (top->areas); n1; nextnode (n1))
+  for (n1 = listhead (ospf->areas); n1; nextnode (n1))
     {
       if ((area = getdata (n1)) == NULL)
         continue;
@@ -3032,22 +2969,25 @@
             need_to_flush_ase = 1;
         }
 
-      foreach_lsa (SUMMARY_LSDB (area), NULL, 0, ospf_lsa_flush_schedule);
-      foreach_lsa (ASBR_SUMMARY_LSDB (area), NULL, 0, ospf_lsa_flush_schedule);
+      LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
+	ospf_lsa_flush_schedule (ospf, lsa);
+      LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
+	ospf_lsa_flush_schedule (ospf, lsa);
 #ifdef HAVE_OPAQUE_LSA
-      foreach_lsa (OPAQUE_LINK_LSDB (area),
-                   NULL, 0, ospf_lsa_flush_schedule);
-      foreach_lsa (OPAQUE_AREA_LSDB (area),
-                   NULL, 0, ospf_lsa_flush_schedule);
+      LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
+	ospf_lsa_flush_schedule (ospf, lsa);
+      LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
+	ospf_lsa_flush_schedule (ospf, lsa);
 #endif /* HAVE_OPAQUE_LSA */
     }
 
   if (need_to_flush_ase)
     {
-        foreach_lsa (EXTERNAL_LSDB (top), NULL, 0, ospf_lsa_flush_schedule);
+      LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
+	ospf_lsa_flush_schedule (ospf, lsa);
 #ifdef HAVE_OPAQUE_LSA
-        foreach_lsa (OPAQUE_AS_LSDB (top),
-                     NULL, 0, ospf_lsa_flush_schedule);
+      LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
+	ospf_lsa_flush_schedule (ospf, lsa);
 #endif /* HAVE_OPAQUE_LSA */
     }
 
@@ -3055,10 +2995,10 @@
    * Make sure that the MaxAge LSA remover is executed immediately,
    * without conflicting to other threads.
    */
-  if (top->t_maxage != NULL)
+  if (ospf->t_maxage != NULL)
     {
-      OSPF_TIMER_OFF (top->t_maxage);
-      thread_execute (master, ospf_maxage_lsa_remover, top, 0);
+      OSPF_TIMER_OFF (ospf->t_maxage);
+      thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
     }
 
   return;
@@ -3068,7 +3008,7 @@
 /* If there is self-originated LSA, then return 1, otherwise return 0. */
 /* An interface-independent version of ospf_lsa_is_self_originated */
 int 
-ospf_lsa_is_self_originated (struct ospf_lsa *lsa)
+ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   listnode node;
 
@@ -3080,17 +3020,17 @@
   SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
 
   /* AdvRouter and Router ID is the same. */
-  if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf_top->router_id))
+  if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
     SET_FLAG (lsa->flags, OSPF_LSA_SELF);
 
   /* LSA is router-LSA. */
   else if (lsa->data->type == OSPF_ROUTER_LSA &&
-      IPV4_ADDR_SAME (&lsa->data->id, &ospf_top->router_id))
+      IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
     SET_FLAG (lsa->flags, OSPF_LSA_SELF);
 
   /* LSA is network-LSA.  Compare Link ID with all interfaces. */
   else if (lsa->data->type == OSPF_NETWORK_LSA)
-    for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+    for (node = listhead (ospf->oiflist); node; nextnode (node))
       {
 	struct ospf_interface *oi = getdata (node);
 
@@ -3110,7 +3050,8 @@
 
 /* Get unique Link State ID. */
 struct in_addr
-ospf_lsa_unique_id (struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
+ospf_lsa_unique_id (struct ospf *ospf,
+		    struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
 {
   struct ospf_lsa *lsa;
   struct in_addr mask, id;
@@ -3118,7 +3059,7 @@
   id = p->prefix;
 
   /* Check existence of LSA instance. */
-  lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf_top->router_id);
+  lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
   if (lsa)
     {
       struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
@@ -3138,8 +3079,8 @@
 	  masklen2ip (p->prefixlen, &mask);
 
 	  id.s_addr = p->prefix.s_addr | (~mask.s_addr);
-	  lsa = ospf_lsdb_lookup_by_id (ospf_top->lsdb, type,
-				       id, ospf_top->router_id);
+	  lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
+				       id, ospf->router_id);
 	  if (lsa)
 	    {
 	      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
@@ -3176,6 +3117,7 @@
 ospf_lsa_action (struct thread *t)
 {
   struct lsa_action *data;
+  struct ospf *ospf = ospf_top;
 
   data = THREAD_ARG (t);
 
@@ -3195,13 +3137,13 @@
       ospf_flood_through_area (data->area, NULL, data->lsa);
       break;
     case LSA_ACTION_FLOOD_AS:
-      ospf_flood_through_as (NULL, data->lsa);
+      ospf_flood_through_as (ospf, NULL, data->lsa);
       break;
     case LSA_ACTION_FLUSH_AREA:
       ospf_lsa_flush_area (data->lsa, data->area);
       break;
     case LSA_ACTION_FLUSH_AS:
-      ospf_lsa_flush_as (data->lsa);
+      ospf_lsa_flush_as (ospf, data->lsa);
       break;
     }
 
@@ -3243,7 +3185,7 @@
 
 /* LSA Refreshment functions. */
 void
-ospf_lsa_refresh (struct ospf_lsa *lsa)
+ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   struct external_info *ei;
   assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
@@ -3255,17 +3197,17 @@
     case OSPF_NETWORK_LSA: 
       break;
     case OSPF_SUMMARY_LSA:
-      ospf_summary_lsa_refresh (lsa);
+      ospf_summary_lsa_refresh (ospf, lsa);
       break;
     case OSPF_ASBR_SUMMARY_LSA:
-      ospf_summary_asbr_lsa_refresh (lsa);
+      ospf_summary_asbr_lsa_refresh (ospf, lsa);
       break;
     case OSPF_AS_EXTERNAL_LSA:
       ei = ospf_external_info_check (lsa);
       if (ei)
-	ospf_external_lsa_refresh (lsa, ei, LSA_REFRESH_FORCE);
+	ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
       else
-	ospf_lsa_flush_as (lsa);
+	ospf_lsa_flush_as (ospf, lsa);
       break;
 #ifdef HAVE_OPAQUE_LSA
     case OSPF_OPAQUE_LINK_LSA:
@@ -3280,7 +3222,7 @@
 }
 
 void
-ospf_refresher_register_lsa (struct ospf *top, struct ospf_lsa *lsa)
+ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   u_int16_t index, current_index;
   
@@ -3302,8 +3244,8 @@
       if (delay < 0)
 	delay = 0;
 
-      current_index = top->lsa_refresh_queue.index +
-	(time (NULL) - top->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
+      current_index = ospf->lsa_refresh_queue.index +
+	(time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
       
       index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
 	% (OSPF_LSA_REFRESHER_SLOTS);
@@ -3311,9 +3253,9 @@
       if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
 	zlog_info ("LSA[Refresh]: lsa with age %d added to index %d",
 		   LS_AGE (lsa), index);
-      if (!top->lsa_refresh_queue.qs[index])
-	top->lsa_refresh_queue.qs[index] = list_new ();
-      listnode_add (top->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
+      if (!ospf->lsa_refresh_queue.qs[index])
+	ospf->lsa_refresh_queue.qs[index] = list_new ();
+      listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
       lsa->refresh_list = index;
       if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
 	zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index);
@@ -3321,17 +3263,17 @@
 }
 
 void
-ospf_refresher_unregister_lsa (struct ospf *top, struct ospf_lsa *lsa)
+ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
   if (lsa->refresh_list >= 0)
     {
-      list refresh_list = top->lsa_refresh_queue.qs[lsa->refresh_list];
+      list refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
       listnode_delete (refresh_list, lsa);
       if (!listcount (refresh_list))
 	{
 	  list_free (refresh_list);
-	  top->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
+	  ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
 	}
       ospf_lsa_unlock (lsa);
       lsa->refresh_list = -1;
@@ -3343,7 +3285,7 @@
 {
   list refresh_list;
   listnode node;
-  struct ospf *top = THREAD_ARG (t);
+  struct ospf *ospf = THREAD_ARG (t);
   int i;
   list lsa_to_refresh = list_new ();
 
@@ -3351,27 +3293,27 @@
     zlog_info ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
 
   
-  i = top->lsa_refresh_queue.index;
+  i = ospf->lsa_refresh_queue.index;
   
-  top->lsa_refresh_queue.index =
-    (top->lsa_refresh_queue.index +
-     (time (NULL) - top->lsa_refresher_started) / OSPF_LSA_REFRESHER_GRANULARITY)
+  ospf->lsa_refresh_queue.index =
+    (ospf->lsa_refresh_queue.index +
+     (time (NULL) - ospf->lsa_refresher_started) / OSPF_LSA_REFRESHER_GRANULARITY)
     % OSPF_LSA_REFRESHER_SLOTS;
 
   if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
     zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
-	       top->lsa_refresh_queue.index);
+	       ospf->lsa_refresh_queue.index);
 
-  for (;i != top->lsa_refresh_queue.index;
+  for (;i != ospf->lsa_refresh_queue.index;
        i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
     {
       if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
 	zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh index %d", i);
 
-      refresh_list = top->lsa_refresh_queue.qs [i];
+      refresh_list = ospf->lsa_refresh_queue.qs [i];
       
-      top->lsa_refresh_queue.qs [i] = NULL;
-      
+      ospf->lsa_refresh_queue.qs [i] = NULL;
+
       if (refresh_list)
 	{
 	  for (node = listhead (refresh_list); node;)
@@ -3393,12 +3335,12 @@
 	}
     }
 
-  top->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
-					   top, top->lsa_refresh_interval);
-  top->lsa_refresher_started = time (NULL);
+  ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
+					   ospf, ospf->lsa_refresh_interval);
+  ospf->lsa_refresher_started = time (NULL);
 
   for (node = listhead (lsa_to_refresh); node; nextnode (node))
-    ospf_lsa_refresh (getdata (node));
+    ospf_lsa_refresh (ospf, getdata (node));
   
   list_delete (lsa_to_refresh);
   
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index 4303bcd..82d9549 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -207,14 +207,6 @@
 #define IS_LSA_SELF(L)          (CHECK_FLAG ((L)->flags, OSPF_LSA_SELF))
 #define IS_LSA_MAXAGE(L)        (LS_AGE ((L)) == OSPF_LSA_MAXAGE)
 
-#define OSPF_SUMMARY_LSA_SELF_FIND_BY_PREFIX(A,P) \
-        foreach_lsa (SUMMARY_LSDB ((A)), \
-                     (struct prefix_ipv4 *) (P), 0, find_summary)
-
-#define OSPF_SUMMARY_ASBR_LSA_SELF_FIND_BY_PREFIX(A,P) \
-        foreach_lsa (ASBR_SUMMARY_LSDB ((A)), \
-                     (struct prefix_ipv4 *) (P), 0, find_asbr_summary)
-
 #define OSPF_LSA_UPDATE_DELAY		2
 
 #define OSPF_LSA_UPDATE_TIMER_ON(T,F) \
@@ -237,15 +229,16 @@
 u_int16_t ospf_lsa_checksum (struct lsa_header *);
 
 struct stream;
-const char *dump_lsa_key (struct ospf_lsa *lsa);
-u_int32_t lsa_seqnum_increment (struct ospf_lsa *lsa);
-void lsa_header_set (struct stream *s, u_char options, u_char type, struct in_addr id);
-struct ospf_neighbor *ospf_nbr_lookup_ptop (struct route_table *nbrs, struct in_addr router_id);
+const char *dump_lsa_key (struct ospf_lsa *);
+u_int32_t lsa_seqnum_increment (struct ospf_lsa *);
+void lsa_header_set (struct stream *, u_char, u_char, struct in_addr,
+		     struct in_addr);
+struct ospf_neighbor *ospf_nbr_lookup_ptop (struct ospf_interface *);
 
 /* Prototype for LSA primitive. */
 struct ospf_lsa *ospf_lsa_new ();
 struct ospf_lsa *ospf_lsa_dup ();
-void ospf_lsa_free (struct ospf_lsa *lsa);
+void ospf_lsa_free (struct ospf_lsa *);
 struct ospf_lsa *ospf_lsa_lock (struct ospf_lsa *);
 void ospf_lsa_unlock (struct ospf_lsa *);
 void ospf_lsa_discard (struct ospf_lsa *);
@@ -267,17 +260,18 @@
 struct ospf_lsa *ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *,
 						  u_int32_t,
 						  struct ospf_area *);
-struct ospf_lsa *ospf_summary_lsa_refresh (struct ospf_lsa *);
-struct ospf_lsa *ospf_summary_asbr_lsa_refresh (struct ospf_lsa *);
+struct ospf_lsa *ospf_summary_lsa_refresh (struct ospf *, struct ospf_lsa *);
+struct ospf_lsa *ospf_summary_asbr_lsa_refresh (struct ospf *, struct ospf_lsa *);
 
-struct ospf_lsa *ospf_lsa_install (struct ospf_interface *, struct ospf_lsa *);
+struct ospf_lsa *ospf_lsa_install (struct ospf *,
+				   struct ospf_interface *, struct ospf_lsa *);
 
-void ospf_external_lsa_flush (u_char, struct prefix_ipv4 *,
+void ospf_external_lsa_flush (struct ospf *, u_char, struct prefix_ipv4 *,
 			      unsigned int, struct in_addr);
 
-struct in_addr ospf_get_ip_from_ifp (struct ospf_interface *oi);
+struct in_addr ospf_get_ip_from_ifp (struct ospf_interface *);
 
-struct ospf_lsa *ospf_external_lsa_originate (struct external_info *);
+struct ospf_lsa *ospf_external_lsa_originate (struct ospf *, struct external_info *);
 int ospf_external_lsa_originate_timer (struct thread *);
 struct ospf_lsa *ospf_lsa_lookup (struct ospf_area *, u_int32_t,
 				  struct in_addr, struct in_addr);
@@ -286,24 +280,25 @@
 					    struct lsa_header *);
 int ospf_lsa_more_recent (struct ospf_lsa *, struct ospf_lsa *);
 int ospf_lsa_different (struct ospf_lsa *, struct ospf_lsa *);
-void ospf_flush_self_originated_lsas_now (struct ospf *top);
+void ospf_flush_self_originated_lsas_now (struct ospf *);
 
-int ospf_lsa_is_self_originated (struct ospf_lsa *);
+int ospf_lsa_is_self_originated (struct ospf *, struct ospf_lsa *);
 
-int find_summary (struct ospf_lsa *, void *, int);
-int find_asbr_summary (struct ospf_lsa *, void *, int);
+struct ospf_lsa *ospf_lsa_lookup_by_prefix (struct ospf_lsdb *, u_char,
+					    struct prefix_ipv4 *,
+					    struct in_addr);
 
-void ospf_lsa_maxage (struct ospf_lsa *);
+void ospf_lsa_maxage (struct ospf *, struct ospf_lsa *);
 u_int32_t get_metric (u_char *);
 
 int ospf_lsa_maxage_walker (struct thread *);
 
-void ospf_external_lsa_refresh_default (void);
+void ospf_external_lsa_refresh_default (struct ospf *);
 
-void ospf_external_lsa_refresh_type (u_char, int);
-void ospf_external_lsa_refresh (struct ospf_lsa *, struct external_info *ei,
-				int force);
-struct in_addr ospf_lsa_unique_id (struct ospf_lsdb *, u_char,
+void ospf_external_lsa_refresh_type (struct ospf *, u_char, int);
+void ospf_external_lsa_refresh (struct ospf *, struct ospf_lsa *,
+				struct external_info *, int);
+struct in_addr ospf_lsa_unique_id (struct ospf *, struct ospf_lsdb *, u_char,
 				   struct prefix_ipv4 *);
 void ospf_schedule_lsa_flood_area (struct ospf_area *, struct ospf_lsa *);
 void ospf_schedule_lsa_flush_area (struct ospf_area *, struct ospf_lsa *);
@@ -312,16 +307,17 @@
 void ospf_refresher_unregister_lsa (struct ospf *, struct ospf_lsa *);
 int ospf_lsa_refresh_walker (struct thread *);
 
-void ospf_lsa_init ();
+void ospf_lsa_maxage_delete (struct ospf *, struct ospf_lsa *);
 
-void ospf_lsa_maxage_delete (struct ospf_lsa *);
-
-void ospf_discard_from_db (struct ospf_lsdb *, struct ospf_lsa*);
-int ospf_lsa_discard_callback (struct ospf_lsa *, void *, int);
+void ospf_discard_from_db (struct ospf *, struct ospf_lsdb *, struct ospf_lsa*);
 int is_prefix_default (struct prefix_ipv4 *);
 
-int metric_type (u_char);
-int metric_value (u_char);
+int metric_type (struct ospf *, u_char);
+int metric_value (struct ospf *, u_char);
+
+#ifdef HAVE_NSSA
+struct in_addr ospf_get_nssa_ip (struct ospf_area *);
+#endif /* HAVE NSSA */
 
 #ifdef HAVE_NSSA
 struct in_addr ospf_get_nssa_ip (struct ospf_area *);
diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c
index a302aa9..ccef055 100644
--- a/ospfd/ospf_neighbor.c
+++ b/ospfd/ospf_neighbor.c
@@ -202,20 +202,15 @@
 /* Get neighbor count by status.
    Specify status = 0, get all neighbor other than myself. */
 int
-ospf_nbr_count (struct route_table *nbrs, int state)
+ospf_nbr_count (struct ospf_interface *oi, int state)
 {
-  struct route_node *rn;
   struct ospf_neighbor *nbr;
+  struct route_node *rn;
   int count = 0;
 
-  /* Sanity check. */
-  if (nbrs == NULL)
-    return 0;
-
-  for (rn = route_top (nbrs); rn; rn = route_next (rn))
-    if ((nbr = rn->info) != NULL)
-      /* Ignore myself. */
-      if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
+  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
+    if ((nbr = rn->info))
+      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
 	if (state == 0 || nbr->state == state)
 	  count++;
 
@@ -224,23 +219,18 @@
 
 #ifdef HAVE_OPAQUE_LSA
 int
-ospf_opaque_capable_nbr_count (struct route_table *nbrs, int state)
+ospf_nbr_count_opaque_capable (struct ospf_interface *oi)
 {
-  struct route_node *rn;
   struct ospf_neighbor *nbr;
+  struct route_node *rn;
   int count = 0;
 
-  /* Sanity check. */
-  if (nbrs == NULL)
-    return 0;
-
-  for (rn = route_top (nbrs); rn; rn = route_next (rn))
-    if ((nbr = rn->info) != NULL)
-      /* Ignore myself. */
-      if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
-	if ((state == 0 || nbr->state == state)
-	&&  CHECK_FLAG (nbr->options, OSPF_OPTION_O))
-	  count++;
+  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
+    if ((nbr = rn->info))
+      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
+	if (nbr->state == NSM_Full)
+	  if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
+	    count++;
 
   return count;
 }
diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c
index 5730357..a8efdcc 100644
--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -222,13 +222,8 @@
 }
 
 int
-ospf_db_summary_add (struct ospf_lsa *lsa, void *v, int i)
+ospf_db_summary_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
 {
-  struct ospf_neighbor *nbr = (struct ospf_neighbor *) v;
-
-  if (lsa == NULL)
-    return 0;
-
 #ifdef HAVE_OPAQUE_LSA
   switch (lsa->data->type)
     {
@@ -283,73 +278,58 @@
 
 
 
-#ifdef HAVE_OPAQUE_LSA
-/* The area link state database consists of the router-LSAs,
-   network-LSAs, summary-LSAs, and type-9/10 opaque-LSAs contained
-			     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   in the area structure, along with the AS-external and type-11
-						     ^^^^^^^^^^^
-   opaque LSAs contained in the global structure.
-   ^^^^^^
-   AS-external and type-11 opaque LSAs are omitted from a virtual
-	       ^^^^^^^^^^^^^^^^^^
-   neighbor's Database summary list. AS-external and type-11 opaque
-						 ^^^^^^^^^^^^^^^^^^
-   LSAs are omitted from the Database summary list if the area has
-   been configured as a stub. */
-#else /* HAVE_OPAQUE_LSA */
 /* The area link state database consists of the router-LSAs,
    network-LSAs and summary-LSAs contained in the area structure,
-   along with the AS-external- LSAs contained in the global structure.
-   AS- external-LSAs are omitted from a virtual neighbor's Database
+   along with the AS-external-LSAs contained in the global structure.
+   AS-external-LSAs are omitted from a virtual neighbor's Database
    summary list.  AS-external-LSAs are omitted from the Database
    summary list if the area has been configured as a stub. */
-#endif /* HAVE_OPAQUE_LSA */
 int
 nsm_negotiation_done (struct ospf_neighbor *nbr)
 {
-  struct ospf_area *area;
+  struct ospf_area *area = nbr->oi->area;
+  struct ospf_lsa *lsa;
+  struct route_node *rn;
 
-  area = nbr->oi->area;
+  LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
+    ospf_db_summary_add (nbr, lsa);
+  LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
+    ospf_db_summary_add (nbr, lsa);
+  LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
+    ospf_db_summary_add (nbr, lsa);
+  LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
+    ospf_db_summary_add (nbr, lsa);
 
-  foreach_lsa (ROUTER_LSDB (area), nbr, 0, ospf_db_summary_add);
-  foreach_lsa (NETWORK_LSDB (area), nbr, 0, ospf_db_summary_add);
-  foreach_lsa (SUMMARY_LSDB (area), nbr, 0, ospf_db_summary_add);
-  foreach_lsa (ASBR_SUMMARY_LSDB (area), nbr, 0, ospf_db_summary_add);
-  
 #ifdef HAVE_OPAQUE_LSA
   /* Process only if the neighbor is opaque capable. */
   if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
     {
-      foreach_lsa (OPAQUE_LINK_LSDB (area), nbr, 0, ospf_db_summary_add);
-      foreach_lsa (OPAQUE_AREA_LSDB (area), nbr, 0, ospf_db_summary_add);
+      LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
+	ospf_db_summary_add (nbr, lsa);
+      LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
+	ospf_db_summary_add (nbr, lsa);
     }
 #endif /* HAVE_OPAQUE_LSA */
 
-  if (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK &&
-      area->external_routing == OSPF_AREA_DEFAULT)
-    foreach_lsa (EXTERNAL_LSDB (ospf_top), nbr, 0, ospf_db_summary_add);
+  if (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK
+      && area->external_routing == OSPF_AREA_DEFAULT)
+    LSDB_LOOP (EXTERNAL_LSDB (nbr->oi->ospf), rn, lsa)
+      ospf_db_summary_add (nbr, lsa);
 
 #ifdef HAVE_OPAQUE_LSA
-  if (CHECK_FLAG (nbr->options, OSPF_OPTION_O) &&
-      (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK &&
-       area->external_routing == OSPF_AREA_DEFAULT))
-    foreach_lsa (OPAQUE_AS_LSDB (ospf_top),
-		 nbr, 0, ospf_db_summary_add);
+  if (CHECK_FLAG (nbr->options, OSPF_OPTION_O)
+      && (nbr->oi->type != OSPF_IFTYPE_VIRTUALLINK
+	  && area->external_routing == OSPF_AREA_DEFAULT))
+    LSDB_LOOP (OPAQUE_AS_LSDB (nbr->oi->ospf), rn, lsa)
+      ospf_db_summary_add (nbr, lsa);
 #endif /* HAVE_OPAQUE_LSA */
 
-  /* OSPF_NSM_TIMER_OFF (nbr->t_db_desc); */
-
   return 0;
 }
 
 int
 nsm_exchange_done (struct ospf_neighbor *nbr)
 {
-  struct ospf_interface *oi;
-
-  oi = nbr->oi;
-
   if (ospf_ls_request_isempty (nbr))
     return NSM_Full;
 
@@ -382,18 +362,18 @@
   next_state = nbr->state;
 
   /* These netowork types must be adjacency. */
-  if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
-      oi->type == OSPF_IFTYPE_POINTOMULTIPOINT ||
-      oi->type == OSPF_IFTYPE_VIRTUALLINK)
+  if (oi->type == OSPF_IFTYPE_POINTOPOINT
+      || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT
+      || oi->type == OSPF_IFTYPE_VIRTUALLINK)
     flag = 1;
 
   /* Router itself is the DRouter or the BDRouter. */
-  if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi)) ||
-      IPV4_ADDR_SAME (&oi->address->u.prefix4, &BDR (oi)))
+  if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))
+      || IPV4_ADDR_SAME (&oi->address->u.prefix4, &BDR (oi)))
     flag = 1;
 
-  if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &DR (oi)) ||
-      IPV4_ADDR_SAME (&nbr->address.u.prefix4, &BDR (oi)))
+  if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &DR (oi))
+      || IPV4_ADDR_SAME (&nbr->address.u.prefix4, &BDR (oi)))
     flag = 1;
 
   if (nbr->state == NSM_TwoWay && flag == 1)
@@ -683,7 +663,7 @@
 void
 nsm_change_state (struct ospf_neighbor *nbr, int state)
 {
-  struct ospf_interface *oi;
+  struct ospf_interface *oi = nbr->oi;
   struct ospf_area *vl_area = NULL;
   u_char old_state;
   int x;
@@ -705,10 +685,8 @@
   /* Statistics. */
   nbr->state_change++;
 
-  oi = nbr->oi;
-
   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
-    vl_area = ospf_area_lookup_by_area_id (oi->vl_data->vl_area_id);
+    vl_area = ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id);
   
   /* One of the neighboring routers changes to/from the FULL state. */
   if ((old_state != NSM_Full && state == NSM_Full) ||
@@ -719,31 +697,31 @@
 	  oi->full_nbrs++;
 	  oi->area->full_nbrs++;
 
-          ospf_check_abr_status ();
+          ospf_check_abr_status (oi->ospf);
 
 	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area)
             if (++vl_area->full_vls == 1)
-	      ospf_schedule_abr_task ();
+	      ospf_schedule_abr_task (oi->ospf);
 
 	  /* kevinm: refresh any redistributions */
-	  for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++) {
-	    if (x == ZEBRA_ROUTE_OSPF || x == ZEBRA_ROUTE_OSPF6)
-	      continue;
-	    ospf_external_lsa_refresh_type(x, force);
-	  }
-
+	  for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++)
+	    {
+	      if (x == ZEBRA_ROUTE_OSPF || x == ZEBRA_ROUTE_OSPF6)
+		continue;
+	      ospf_external_lsa_refresh_type (oi->ospf, x, force);
+	    }
 	}
       else
 	{
 	  oi->full_nbrs--;
 	  oi->area->full_nbrs--;
 
-          ospf_check_abr_status ();
+          ospf_check_abr_status (oi->ospf);
 
 	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area)
 	    if (vl_area->full_vls > 0)
 	      if (--vl_area->full_vls == 0)
-		ospf_schedule_abr_task ();
+		ospf_schedule_abr_task (oi->ospf);
  
           /* clear neighbor retransmit list */
           if (!ospf_ls_retransmit_isempty (nbr))
@@ -758,7 +736,7 @@
       if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
 	{
 	  struct ospf_area *vl_area =
-	    ospf_area_lookup_by_area_id (oi->vl_data->vl_area_id);
+	    ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id);
 	  
 	  if (vl_area)
 	    ospf_router_lsa_timer_add (vl_area);
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index fa9c4db..b8ba518 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -545,7 +545,7 @@
       break;
     case OSPF_OPAQUE_AS_LSA:
       top = ospf_top;
-      if (new->area != NULL && (top = new->area->top) == NULL)
+      if (new->area != NULL && (top = new->area->ospf) == NULL)
         {
           free_opaque_info_per_type ((void *) oipt);
           oipt = NULL;
@@ -653,7 +653,7 @@
       break;
     case OSPF_OPAQUE_AS_LSA:
       top = ospf_top;
-      if ((area = lsa->area) != NULL && (top = area->top) == NULL)
+      if ((area = lsa->area) != NULL && (top = area->ospf) == NULL)
         {
           zlog_warn ("Type-11 Opaque-LSA: Reference to OSPF is missing?");
           break; /* Unlikely to happen. */
@@ -1572,7 +1572,7 @@
         }
       break;
     case OSPF_OPAQUE_AREA_LSA:
-      if (lsa->area == NULL || (top = lsa->area->top) == NULL)
+      if (lsa->area == NULL || (top = lsa->area->ospf) == NULL)
         {
           /* Above conditions must have passed. */
           zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
@@ -1581,7 +1581,7 @@
       break;
     case OSPF_OPAQUE_AS_LSA:
       top = ospf_top;
-      if (lsa->area != NULL && (top = lsa->area->top) == NULL)
+      if (lsa->area != NULL && (top = lsa->area->ospf) == NULL)
         {
           /* Above conditions must have passed. */
           zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
@@ -1603,6 +1603,7 @@
 void
 ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)
 {
+  struct ospf *ospf = ospf_top;
   struct ospf_opaque_functab *functab;
 
   if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL
@@ -1619,7 +1620,7 @@
         zlog_info ("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 (lsa);
+      ospf_lsa_maxage (ospf, lsa);
     }
   else
     (* functab->lsa_refresher)(lsa);
@@ -1683,7 +1684,7 @@
           zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: Type-10 Opaque-LSA: Invalid parameter?");
           goto out;
         }
-      if ((top = area->top) == NULL)
+      if ((top = area->ospf) == NULL)
         {
           zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: AREA(%s) -> TOP?", inet_ntoa (area->area_id));
           goto out;
@@ -1712,7 +1713,7 @@
         }
 
       /* Fake "area" to pass "ospf" to a lookup function later. */
-      dummy.top = top;
+      dummy.ospf = top;
       area = &dummy;
 
       func = ospf_opaque_type11_lsa_reoriginate_timer;
@@ -1826,7 +1827,7 @@
 
   if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE)
   ||  ! ospf_if_is_enable (oi)
-  ||    ospf_opaque_capable_nbr_count (oi->nbrs, NSM_Full) == 0)
+  ||    ospf_nbr_count_opaque_capable (oi) == 0)
     {
       if (IS_DEBUG_OSPF_EVENT)
         zlog_info ("Suspend re-origination of Type-9 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);
@@ -1866,7 +1867,7 @@
     }
 
   area = (struct ospf_area *) oipt->owner;
-  if (area == NULL || (top = area->top) == NULL)
+  if (area == NULL || (top = area->ospf) == NULL)
     {
       zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: Something wrong?");
       goto out;
@@ -1878,7 +1879,7 @@
     {
       if ((oi = getdata (node)) == NULL)
         continue;
-      if ((n = ospf_opaque_capable_nbr_count (oi->nbrs, NSM_Full)) > 0)
+      if ((n = ospf_nbr_count_opaque_capable (oi)) > 0)
         break;
     }
 
@@ -1947,6 +1948,7 @@
 void
 ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0)
 {
+  struct ospf *ospf = ospf_top;
   struct opaque_info_per_type *oipt;
   struct opaque_info_per_id *oipi;
   struct ospf_lsa *lsa;
@@ -1978,10 +1980,10 @@
     {
     case OSPF_OPAQUE_LINK_LSA:
     case OSPF_OPAQUE_AREA_LSA:
-      ospf_ls_retransmit_delete_nbr_all (lsa->area, lsa);
+      ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
       break;
     case OSPF_OPAQUE_AS_LSA:
-      ospf_ls_retransmit_delete_nbr_all (NULL, lsa);
+      ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
       break;
     default:
       zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa->data->type);
@@ -2023,6 +2025,7 @@
 void
 ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
 {
+  struct ospf *ospf = ospf_top;
   struct opaque_info_per_type *oipt;
   struct opaque_info_per_id *oipi;
   struct ospf_lsa *lsa;
@@ -2046,10 +2049,10 @@
     {
     case OSPF_OPAQUE_LINK_LSA:
     case OSPF_OPAQUE_AREA_LSA:
-      ospf_ls_retransmit_delete_nbr_all (lsa->area, lsa);
+      ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
       break;
     case OSPF_OPAQUE_AS_LSA:
-      ospf_ls_retransmit_delete_nbr_all (NULL, lsa);
+      ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
       break;
     default:
       zlog_warn ("ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", lsa->data->type);
@@ -2074,7 +2077,7 @@
     zlog_info ("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 (lsa);
+  ospf_lsa_maxage (ospf, lsa);
 
 out:
   return;
@@ -2241,7 +2244,7 @@
           break;
         case OSPF_OPAQUE_AS_LSA:
           SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT);
-          ospf_flood_through_as (NULL/*inbr*/, lsa);
+          ospf_flood_through_as (top, NULL/*inbr*/, lsa);
           break;
         default:
           zlog_warn ("ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)", lsa->data->type);
@@ -2331,7 +2334,7 @@
             continue;
 
           if (! ospf_if_is_enable (oi)
-          ||    ospf_opaque_capable_nbr_count (oi->nbrs, NSM_Full) == 0)
+          ||    ospf_nbr_count_opaque_capable (oi) == 0)
             continue;
 
           ospf_opaque_lsa_originate_schedule (oi, &delay);
@@ -2353,7 +2356,7 @@
       if (IS_DEBUG_OSPF_EVENT)
         zlog_info ("Self-originated type-9 Opaque-LSAs: OI(%s): Flush completed", IF_NAME (oi));
 
-      UNSET_FLAG (oi->area->top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT);
+      UNSET_FLAG (oi->area->ospf->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT);
     }
   return;
 }
@@ -2384,7 +2387,7 @@
       if (IS_DEBUG_OSPF_EVENT)
         zlog_info ("Self-originated type-10 Opaque-LSAs: AREA(%s): Flush completed", inet_ntoa (area->area_id));
 
-      UNSET_FLAG (area->top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT);
+      UNSET_FLAG (area->ospf->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT);
     }
 
   return;
@@ -2481,7 +2484,7 @@
   struct ospf *top = NULL;
   struct ospf_area *area;
 
-  if (oi == NULL || (area = oi->area) == NULL || (top = area->top) == NULL)
+  if (oi == NULL || (area = oi->area) == NULL || (top = area->ospf) == NULL)
     zlog_warn ("Broken relationship for \"OI -> AREA -> OSPF\"?");
 
   return top;
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index d845684..08217af 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -482,22 +482,21 @@
 int
 ospf_write (struct thread *thread)
 {
+  struct ospf *ospf = THREAD_ARG (thread);
   struct ospf_interface *oi;
   struct ospf_packet *op;
   struct sockaddr_in sa_dst;
-  u_char type;
-  int ret;
-  int flags = 0;
   struct ip iph;
   struct msghdr msg;
   struct iovec iov[2];
-  struct ospf *top;
+  u_char type;
+  int ret;
+  int flags = 0;
   listnode node;
   
-  top = THREAD_ARG (thread);
-  top->t_write = NULL;
+  ospf->t_write = NULL;
 
-  node = listhead (top->oi_write_q);
+  node = listhead (ospf->oi_write_q);
   assert (node);
   oi = getdata (node);
   assert (oi);
@@ -507,9 +506,9 @@
   assert (op);
   assert (op->length >= OSPF_HEADER_SIZE);
 
-  if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS) ||
-      op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
-    ospf_if_ipmulticast (top, oi->address, oi->ifp->ifindex);
+  if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
+      || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
+    ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
 
   /* Rewrite the md5 signature & update the seq */
   ospf_make_md5_digest (oi, op);
@@ -529,7 +528,7 @@
 
   iph.ip_hl = sizeof (struct ip) >> 2;
   iph.ip_v = IPVERSION;
-  iph.ip_tos = 0;
+  iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
 #if defined(__NetBSD__) || defined(__FreeBSD__)
   iph.ip_len = iph.ip_hl*4 + op->length;
 #else
@@ -556,7 +555,7 @@
   iov[1].iov_base = STREAM_DATA (op->s);
   iov[1].iov_len = op->length;
 
-  ret = sendmsg (top->fd, &msg, flags);
+  ret = sendmsg (ospf->fd, &msg, flags);
   
   if (ret < 0)
     zlog_warn ("*** sendmsg in ospf_write failed with %s", strerror (errno));
@@ -589,13 +588,13 @@
   if (ospf_fifo_head (oi->obuf) == NULL)
     {
       oi->on_write_q = 0;
-      list_delete_node (top->oi_write_q, node);
+      list_delete_node (ospf->oi_write_q, node);
     }
   
   /* If packets still remain in queue, call write thread. */
-  if (!list_isempty (top->oi_write_q))
-    ospf_top->t_write =                                              
-      thread_add_write (master, ospf_write, top, top->fd);
+  if (!list_isempty (ospf->oi_write_q))
+    ospf->t_write =                                              
+      thread_add_write (master, ospf_write, ospf, ospf->fd);
 
   return 0;
 }
@@ -617,10 +616,8 @@
   hello = (struct ospf_hello *) STREAM_PNT (s);
 
   /* If Hello is myself, silently discard. */
-  if (IPV4_ADDR_SAME (&ospfh->router_id, &ospf_top->router_id)) {
-    zlog_info ("Packet %s [Hello:RECV]: router_id matches our router id");
+  if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
     return;
-  }
 
   /* If incoming interface is passive one, ignore Hello. */
   if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
@@ -681,7 +678,7 @@
 #endif /* REJECT_IF_TBIT_ON */
 
 #ifdef HAVE_OPAQUE_LSA
-  if (CHECK_FLAG (ospf_top->config, OSPF_OPAQUE_CAPABLE)
+  if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
       && CHECK_FLAG (hello->options, OSPF_OPTION_O))
     {
       /*
@@ -823,7 +820,7 @@
       return;
     }
 
-  if (ospf_nbr_bidirectional (&ospf_top->router_id, hello->neighbors,
+  if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
 			      size - OSPF_HELLO_MIN_SIZE))
     {
       OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
@@ -1050,7 +1047,7 @@
 
 #ifdef HAVE_OPAQUE_LSA
   if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
-      && !CHECK_FLAG (ospf_top->config, OSPF_OPAQUE_CAPABLE))
+      && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
     {
       /*
        * This node is not configured to handle O-bit, for now.
@@ -1081,7 +1078,7 @@
       if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
 	  (size == OSPF_DB_DESC_MIN_SIZE))
 	{
-	  if (IPV4_ADDR_CMP (&nbr->router_id, &ospf_top->router_id) > 0)
+	  if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
 	    {
 	      /* We're Slave---obey */
 	      zlog_warn ("Packet[DD]: Negotiation done (Slave).");
@@ -1098,7 +1095,7 @@
       /* Ack from the Slave */
       else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
 	       ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
-	       IPV4_ADDR_CMP (&nbr->router_id, &ospf_top->router_id) < 0)
+	       IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
 	{
 	  zlog_warn ("Packet[DD]: Negotiation done (Master).");
 	  nbr->dd_flags &= ~OSPF_DD_FLAG_I;
@@ -1113,7 +1110,7 @@
       nbr->options = dd->options;
 
 #ifdef HAVE_OPAQUE_LSA
-      if (CHECK_FLAG (ospf_top->config, OSPF_OPAQUE_CAPABLE))
+      if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
         {
           if (IS_DEBUG_OSPF_EVENT)
             zlog_info ("Neighbor[%s] is %sOpaque-capable.",
@@ -1610,8 +1607,8 @@
 	 then take the following actions. */
 
       if (IS_LSA_MAXAGE (lsa) && !current &&
-	  (ospf_nbr_count (oi->nbrs, NSM_Exchange) +
-	   ospf_nbr_count (oi->nbrs, NSM_Loading)) == 0)
+	  (ospf_nbr_count (oi, NSM_Exchange) +
+	   ospf_nbr_count (oi, NSM_Loading)) == 0)
 	{
 	  /* Response Link State Acknowledgment. */
 	  ospf_ls_ack_send (nbr, lsa);
@@ -1623,7 +1620,7 @@
 
 #ifdef HAVE_OPAQUE_LSA
       if (IS_OPAQUE_LSA (lsa->data->type)
-      &&  IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf_top->router_id))
+      &&  IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
         {
           /*
            * Even if initial flushing seems to be completed, there might
@@ -1676,7 +1673,7 @@
 	  (ret = ospf_lsa_more_recent (current, lsa)) < 0)
 	{
 	  /* Actual flooding procedure. */
-	  if (ospf_flood (nbr, current, lsa) < 0)  /* Trap NSSA later. */
+	  if (ospf_flood (oi->ospf, nbr, current, lsa) < 0)  /* Trap NSSA later. */
 	    DISCARD_LSA (lsa, 4);
 	  continue;
 	}
@@ -1973,9 +1970,9 @@
 			  struct ip *iph, struct ospf_header *ospfh)
 {
   struct ospf_interface *rcv_oi;
-  listnode node;
   struct ospf_vl_data *vl_data;
   struct ospf_area *vl_area;
+  listnode node;
 
   if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
       !OSPF_IS_AREA_BACKBONE (ospfh))
@@ -1983,16 +1980,17 @@
 
   if ((rcv_oi = oi) == NULL)
     {
-     if ((rcv_oi = ospf_if_lookup_by_local_addr (ifp, iph->ip_dst)) == NULL)
+     if ((rcv_oi = ospf_if_lookup_by_local_addr (oi->ospf, ifp,
+						 iph->ip_dst)) == NULL)
        return NULL;
     }
 
-  for (node = listhead (ospf_top->vlinks); node; nextnode (node))
+  for (node = listhead (oi->ospf->vlinks); node; nextnode (node))
     {
       if ((vl_data = getdata (node)) == NULL)
 	continue;
       
-      vl_area = ospf_area_lookup_by_area_id (vl_data->vl_area_id);
+      vl_area = ospf_area_lookup_by_area_id (oi->ospf, vl_data->vl_area_id);
       if (!vl_area)
 	continue;
       
@@ -2195,7 +2193,7 @@
 {
   int ret;
   struct stream *ibuf;
-  struct ospf *top;
+  struct ospf *ospf;
   struct ospf_interface *oi;
   struct ip *iph;
   struct ospf_header *ospfh;
@@ -2203,25 +2201,25 @@
   struct interface *ifp;
 
   /* first of all get interface pointer. */
-  top = THREAD_ARG (thread);
-  top->t_read = NULL;
+  ospf = THREAD_ARG (thread);
+  ospf->t_read = NULL;
 
   /* read OSPF packet. */
-  ibuf = ospf_recv_packet (top->fd, &ifp);
+  ibuf = ospf_recv_packet (ospf->fd, &ifp);
   if (ibuf == NULL)
     return -1;
   
   iph = (struct ip *) STREAM_DATA (ibuf);
 
   /* prepare for next packet. */
-  top->t_read = thread_add_read (master, ospf_read, top, top->fd);
+  ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
 
   /* IP Header dump. */
     if (IS_DEBUG_OSPF_PACKET(0, RECV))
 	    ospf_ip_header_dump (ibuf);
 
   /* Self-originated packet should be discarded silently. */
-  if (ospf_if_lookup_by_local_addr (NULL, iph->ip_src))
+  if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
     {
       stream_free (ibuf);
       return 0;
@@ -2234,7 +2232,7 @@
   ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
 
   /* associate packet with ospf interface */
-  oi = ospf_if_lookup_recv_interface (iph->ip_src);
+  oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
   if (ifp && oi && oi->ifp != ifp)
     {
       zlog_warn ("Packet from [%s] received on wrong link %s",
@@ -2336,7 +2334,7 @@
   ospfh->version = (u_char) OSPF_VERSION;
   ospfh->type = (u_char) type;
 
-  ospfh->router_id = ospf_top->router_id;
+  ospfh->router_id = oi->ospf->router_id;
 
   ospfh->checksum = 0;
   ospfh->area_id = oi->area->area_id;
@@ -2453,25 +2451,21 @@
 
   /* Add neighbor seen. */
   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
-    if ((nbr = rn->info) != NULL) {
-      /* ignore 0.0.0.0 node. */
-      if (nbr->router_id.s_addr != 0)
-	if (nbr->state != NSM_Attempt)
-	/* ignore Down neighbor. */
-	if (nbr->state != NSM_Down)
-	  /* this is myself for DR election. */
-	  if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
+    if ((nbr = rn->info))
+      if (nbr->router_id.s_addr != 0)	/* Ignore 0.0.0.0 node. */
+	if (nbr->state != NSM_Attempt)  /* Ignore Down neighbor. */
+	if (nbr->state != NSM_Down)     /* This is myself for DR election. */
+	  if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
 	    {
 	      /* Check neighbor is sane? */
-	      if (nbr->d_router.s_addr != 0 &&
-		  IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4) &&
-		  IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
-		flag = 0;
+	      if (nbr->d_router.s_addr != 0
+		  && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
+		  && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
+		flag = 1;
 
 	      stream_put_ipv4 (s, nbr->router_id.s_addr);
 	      length += 4;
 	    }
-    }
 
   /* Let neighbor generate BackupSeen. */
   if (flag == 1)
@@ -2503,7 +2497,7 @@
   /* Set Options. */
   options = OPTIONS (oi);
 #ifdef HAVE_OPAQUE_LSA
-  if (CHECK_FLAG (ospf_top->config, OSPF_OPAQUE_CAPABLE))
+  if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
     {
       if (IS_SET_DD_I (nbr->dd_flags)
       ||  CHECK_FLAG (nbr->options, OSPF_OPTION_O))
diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c
index 4f9af31..c3e3468 100644
--- a/ospfd/ospf_snmp.c
+++ b/ospfd/ospf_snmp.c
@@ -496,15 +496,15 @@
 /* The administrative status of OSPF.  When OSPF is enbled on at least
    one interface return 1. */
 int
-ospf_admin_stat ()
+ospf_admin_stat (struct ospf *ospf)
 {
   listnode node;
   struct ospf_interface *oi;
 
-  if (! ospf_top)
+  if (ospf == NULL)
     return 0;
 
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
     {
       oi = getdata (node);
 
@@ -518,6 +518,8 @@
 ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
 		  int exact, size_t *var_len, WriteMethod **write_method)
 {
+  struct ospf *ospf = ospf_top;
+
   /* Check whether the instance identifier is valid */
   if (smux_header_generic (v, name, length, exact, var_len, write_method)
       == MATCH_FAILED)
@@ -528,14 +530,14 @@
     {
     case OSPFROUTERID:		/* 1 */
       /* Router-ID of this OSPF instance. */
-      if (ospf_top)
-	return SNMP_IPADDRESS (ospf_top->router_id);
+      if (ospf)
+	return SNMP_IPADDRESS (ospf->router_id);
       else
 	return SNMP_IPADDRESS (ospf_empty_addr);
       break;
     case OSPFADMINSTAT:		/* 2 */
       /* The administrative status of OSPF in the router. */
-      if (ospf_admin_stat ())
+      if (ospf_admin_stat (ospf))
 	return SNMP_INTEGER (OSPF_STATUS_ENABLED);
       else
 	return SNMP_INTEGER (OSPF_STATUS_DISABLED);
@@ -546,22 +548,22 @@
       break;
     case OSPFAREABDRRTRSTATUS:	/* 4 */
       /* Area Border router status. */
-      if (ospf_top && CHECK_FLAG (ospf_top->flags, OSPF_FLAG_ABR))
+      if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
 	return SNMP_INTEGER (SNMP_TRUE);
       else
 	return SNMP_INTEGER (SNMP_FALSE);
       break;
     case OSPFASBDRRTRSTATUS:	/* 5 */
       /* AS Border router status. */
-      if (ospf_top && CHECK_FLAG (ospf_top->flags, OSPF_FLAG_ASBR))
+      if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
 	return SNMP_INTEGER (SNMP_TRUE);
       else
 	return SNMP_INTEGER (SNMP_FALSE);
       break;
     case OSPFEXTERNLSACOUNT:	/* 6 */
       /* External LSA counts. */
-      if (ospf_top)
-	return SNMP_INTEGER (ospf_lsdb_count_all (ospf_top->lsdb));
+      if (ospf)
+	return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
       else
 	return SNMP_INTEGER (0);
       break;
@@ -575,16 +577,16 @@
       break;
     case OSPFORIGINATENEWLSAS:	/* 9 */
       /* The number of new link-state advertisements. */
-      if (ospf_top)
-	return SNMP_INTEGER (ospf_top->lsa_originate_count);
+      if (ospf)
+	return SNMP_INTEGER (ospf->lsa_originate_count);
       else
 	return SNMP_INTEGER (0);
       break;
     case OSPFRXNEWLSAS:		/* 10 */
       /* The number of link-state advertisements received determined
          to be new instantiations. */
-      if (ospf_top)
-	return SNMP_INTEGER (ospf_top->rx_lsa_count);
+      if (ospf)
+	return SNMP_INTEGER (ospf->rx_lsa_count);
       else
 	return SNMP_INTEGER (0);
       break;
@@ -612,7 +614,7 @@
 }
 
 struct ospf_area *
-ospf_area_lookup_next (struct in_addr *area_id, int first)
+ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
 {
   struct ospf_area *area;
   listnode node;
@@ -622,7 +624,7 @@
 
   if (first)
     {
-      node = listhead (ospf_top->areas);
+      node = listhead (ospf->areas);
       if (node)
 	{
 	  area = getdata (node);
@@ -631,7 +633,7 @@
 	}
       return NULL;
     }
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     {
       area = getdata (node);
 
@@ -648,10 +650,11 @@
 ospfAreaLookup (struct variable *v, oid name[], size_t *length,
 		struct in_addr *addr, int exact)
 {
-  int len;
+  struct ospf *ospf = ospf_top;
   struct ospf_area *area;
+  int len;
 
-  if (! ospf_top)
+  if (ospf == NULL)
     return NULL;
 
   if (exact)
@@ -662,7 +665,7 @@
 
       oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
 
-      area = ospf_area_lookup_by_area_id (*addr);
+      area = ospf_area_lookup_by_area_id (ospf, *addr);
 
       return area;
     }
@@ -674,7 +677,7 @@
       
       oid2in_addr (name + v->namelen, len, addr);
 
-      area = ospf_area_lookup_next (addr, len == 0 ? 1 : 0);
+      area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
 
       if (area == NULL)
 	return NULL;
@@ -779,8 +782,9 @@
 ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
 		    struct in_addr *addr, int exact)
 {
-  int len;
+  struct ospf *ospf = ospf_top;
   struct ospf_area *area;
+  int len;
 
   if (! ospf_top)
     return NULL;
@@ -798,7 +802,7 @@
 
       oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
 
-      area = ospf_area_lookup_by_area_id (*addr);
+      area = ospf_area_lookup_by_area_id (ospf, *addr);
 
       if (area->external_routing == OSPF_AREA_STUB)
 	return area;
@@ -906,6 +910,7 @@
 		struct in_addr *area_id, u_char *type,
 		struct in_addr *ls_id, struct in_addr *router_id, int exact)
 {
+  struct ospf *ospf = ospf_top;
   struct ospf_area *area;
   struct ospf_lsa *lsa;
   int len;
@@ -929,7 +934,7 @@
 
       /* Lookup area first. */
       oid2in_addr (offset, IN_ADDR_SIZE, area_id);
-      area = ospf_area_lookup_by_area_id (*area_id);
+      area = ospf_area_lookup_by_area_id (ospf, *area_id);
       if (! area)
 	return NULL;
       offset += IN_ADDR_SIZE;
@@ -962,9 +967,9 @@
 
       /* First we search area. */
       if (len == IN_ADDR_SIZE)
-	area = ospf_area_lookup_by_area_id (*area_id);
+	area = ospf_area_lookup_by_area_id (ospf, *area_id);
       else
-	area = ospf_area_lookup_next (area_id, len == 0 ? 1 : 0);
+	area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
 
       if (area == NULL)
 	return NULL;
@@ -1038,7 +1043,7 @@
 	      return lsa;
 	    }
 	}
-      while ((area = ospf_area_lookup_next (area_id, 0)) != NULL);
+      while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
     }
   return NULL;
 }
@@ -1116,6 +1121,7 @@
   oid *offset;
   int offsetlen;
   int len;
+  struct ospf *ospf = ospf_top;
   struct ospf_area *area;
   struct ospf_area_range *range;
   struct prefix_ipv4 p;
@@ -1134,7 +1140,7 @@
       /* Lookup area first. */
       oid2in_addr (offset, IN_ADDR_SIZE, area_id);
 
-      area = ospf_area_lookup_by_area_id (*area_id);
+      area = ospf_area_lookup_by_area_id (ospf, *area_id);
       if (! area)
 	return NULL;
 
@@ -1160,9 +1166,9 @@
 
       /* First we search area. */
       if (len == IN_ADDR_SIZE)
-	area = ospf_area_lookup_by_area_id (*area_id);
+	area = ospf_area_lookup_by_area_id (ospf,*area_id);
       else
-	area = ospf_area_lookup_next (area_id, len == 0 ? 1 : 0);
+	area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
 
       if (area == NULL)
 	return NULL;
@@ -1197,7 +1203,7 @@
 	      return range;
 	    }
 	}
-      while ((area = ospf_area_lookup_next (area_id, 0)) != NULL);
+      while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
     }
   return NULL;
 }
@@ -1210,9 +1216,10 @@
   struct in_addr area_id;
   struct in_addr range_net;
   struct in_addr mask;
+  struct ospf *ospf = ospf_top;
   
   /* Check OSPF instance. */
-  if (! ospf_top)
+  if (ospf == NULL)
     return NULL;
 
   memset (&area_id, 0, IN_ADDR_SIZE);
@@ -1258,8 +1265,9 @@
 {
   int len;
   struct ospf_nbr_nbma *nbr_nbma;
+  struct ospf *ospf = ospf_top;
 
-  if (! ospf_top)
+  if (ospf == NULL)
     return NULL;
 
   if (exact)
@@ -1274,7 +1282,7 @@
 
       oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
 
-      nbr_nbma = ospf_nbr_nbma_lookup (ospf_top, *addr);
+      nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
 
       return nbr_nbma;
     }
@@ -1286,7 +1294,7 @@
       
       oid2in_addr (name + v->namelen, len, addr);
 
-      nbr_nbma = ospf_nbr_nbma_lookup_next (addr, len == 0 ? 1 : 0);
+      nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
 
       if (nbr_nbma == NULL)
 	return NULL;
@@ -1310,9 +1318,10 @@
   struct ospf_nbr_nbma *nbr_nbma;
   struct ospf_interface *oi;
   struct in_addr addr;
+  struct ospf *ospf = ospf_top;
 
   /* Check OSPF instance. */
-  if (! ospf_top)
+  if (ospf == NULL)
     return NULL;
 
   memset (&addr, 0, sizeof (struct in_addr));
@@ -1600,19 +1609,20 @@
   unsigned int ifindex;
   struct in_addr ifaddr;
   struct ospf_interface *oi;
+  struct ospf *ospf = ospf_top;
 
   ifindex = 0;
   memset (&ifaddr, 0, sizeof (struct in_addr));
 
   /* Check OSPF instance. */
-  if (! ospf_top)
+  if (ospf == NULL)
     return NULL;
 
   ifp = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
   if (ifp == NULL)
     return NULL;
 
-  oi = ospf_if_lookup_by_local_addr (ifp, ifaddr);
+  oi = ospf_if_lookup_by_local_addr (ospf, ifp, ifaddr);
   if (oi == NULL)
     return NULL;
 
@@ -1771,19 +1781,20 @@
   unsigned int ifindex;
   struct in_addr ifaddr;
   struct ospf_interface *oi;
+  struct ospf *ospf = ospf_top;
 
   ifindex = 0;
   memset (&ifaddr, 0, sizeof (struct in_addr));
 
   /* Check OSPF instance. */
-  if (! ospf_top)
+  if (ospf == NULL)
     return NULL;
 
   ifp = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
   if (ifp == NULL)
     return NULL;
 
-  oi = ospf_if_lookup_by_local_addr (ifp, ifaddr);
+  oi = ospf_if_lookup_by_local_addr (ospf, ifp, ifaddr);
   if (oi == NULL)
     return NULL;
 
@@ -2025,14 +2036,15 @@
 }
 
 struct ospf_neighbor *
-ospf_snmp_nbr_lookup (struct in_addr *nbr_addr, unsigned int *ifindex)
+ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
+		      unsigned int *ifindex)
 {
   struct listnode *nn;
   struct ospf_interface *oi;
   struct ospf_neighbor *nbr;
   struct route_node *rn;
 
-  LIST_LOOP (ospf_top->oiflist, oi, nn)
+  LIST_LOOP (ospf->oiflist, oi, nn)
     {
       for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
 	if ((nbr = rn->info) != NULL
@@ -2059,8 +2071,9 @@
   struct ospf_neighbor *nbr;
   struct route_node *rn;
   struct ospf_neighbor *min = NULL;
+  struct ospf *ospf = ospf_top;
 
-  LIST_LOOP (ospf_top->oiflist, oi, nn)
+  LIST_LOOP (ospf->oiflist, oi, nn)
     {
       for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
 	if ((nbr = rn->info) != NULL
@@ -2100,6 +2113,7 @@
   int len;
   int first;
   struct ospf_neighbor *nbr;
+  struct ospf *ospf = ospf_top;
 
   if (exact)
     {
@@ -2109,7 +2123,7 @@
       oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
       *ifindex = name[v->namelen + IN_ADDR_SIZE];
 
-      return ospf_snmp_nbr_lookup (nbr_addr, ifindex);
+      return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
     }
   else
     {
@@ -2210,12 +2224,13 @@
   struct ospf_vl_data *vl_data;
   struct in_addr area_id;
   struct in_addr neighbor;
+  struct ospf *ospf = ospf_top;
 
   memset (&area_id, 0, sizeof (struct in_addr));
   memset (&neighbor, 0, sizeof (struct in_addr));
 
   /* Check OSPF instance. */
-  if (! ospf_top)
+  if (ospf == NULL)
     return NULL;
 
   vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
@@ -2266,6 +2281,7 @@
   u_char lsa_type;
   int len;
   struct ospf_lsa *lsa;
+  struct ospf *ospf = ospf_top;
 
   if (exact)
     {
@@ -2288,7 +2304,7 @@
       /* Router ID. */
       oid2in_addr (offset, IN_ADDR_SIZE, router_id);
 
-      return ospf_lsdb_lookup_by_id (ospf_top->lsdb, *type, *ls_id, *router_id);
+      return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
     }
   else
     {
@@ -2322,7 +2338,7 @@
 
       oid2in_addr (offset, len, router_id);
 
-      lsa = ospf_lsdb_lookup_by_id_next (ospf_top->lsdb, *type, *ls_id,
+      lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
 					*router_id, first);
 
       if (lsa)
@@ -2354,13 +2370,14 @@
   u_char type;
   struct in_addr ls_id;
   struct in_addr router_id;
+  struct ospf *ospf = ospf_top;
 
   type = OSPF_AS_EXTERNAL_LSA;
   memset (&ls_id, 0, sizeof (struct in_addr));
   memset (&router_id, 0, sizeof (struct in_addr));
 
   /* Check OSPF instance. */
-  if (! ospf_top)
+  if (ospf == NULL)
     return NULL;
 
   lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 6e92bb2..1586a3a 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -365,39 +365,41 @@
 	      
 	      if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT)
 		{
-		  /* check for PtMP, signified by PtP link V->W with link_data our PtMP interface */
-                  oi = ospf_if_is_configured(&l->link_data);
+		  /* Check for PtMP, signified by PtP link V->W
+		     with link_data our PtMP interface. */
+                  oi = ospf_if_is_configured (area->ospf, &l->link_data);
                   if (oi && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
 		    {
-		    
-		      struct prefix_ipv4 * la = prefix_ipv4_new();
-		      la->prefixlen = oi->address->prefixlen;
-		      
-		      /* we link to them on PtMP interface - find the interface on w */
+		      struct prefix_ipv4 la;
+		      la.prefixlen = oi->address->prefixlen;
+		      /* We link to them on PtMP interface
+			 - find the interface on w */
 		      while ((l2 = ospf_get_next_link (w, v, l2)))
 			{
-			  la->prefix = l2->link_data;
+			  la.prefix = l2->link_data;
 			  
-			  if (prefix_cmp((struct prefix *)la, oi->address) == 0)
+			  if (prefix_cmp ((struct prefix *)&la,
+					  oi->address) == 0)
 			    /* link_data is on our PtMP network */
 			    break;
-			  
 			}
 		    }
 		  else
 		    {                                
 		      while ((l2 = ospf_get_next_link (w, v, l2)))
 			{
-			  oi = ospf_if_is_configured (&(l2->link_data));
+			  oi = ospf_if_is_configured (area->ospf,
+						      &(l2->link_data));
 			  
 			  if (oi == NULL)
 			    continue;
 			  
-			  if (!IPV4_ADDR_SAME (&oi->address->u.prefix4, &l->link_data))
+			  if (!IPV4_ADDR_SAME (&oi->address->u.prefix4,
+					       &l->link_data))
 			    continue;
 			  
 			  break;
-                      }
+			}
 		    }
 		  
 		  if (oi && l2)
@@ -414,7 +416,7 @@
 	{
 	  while ((l = ospf_get_next_link (v, w, l)))
 	    {
-	      oi = ospf_if_is_configured (&(l->link_data));
+	      oi = ospf_if_is_configured (area->ospf, &(l->link_data));
 	      if (oi)
 		{
 		  nh = vertex_nexthop_new (v);
@@ -995,7 +997,7 @@
   /* Increment SPF Calculation Counter. */
   area->spf_calculation++;
 
-  ospf_top->ts_spf = time (NULL);
+  area->ospf->ts_spf = time (NULL);
 
   if (IS_DEBUG_OSPF_EVENT)
     zlog_info ("ospf_spf_calculate: Stop");
@@ -1003,32 +1005,30 @@
 
 /* Timer for SPF calculation. */
 int
-ospf_spf_calculate_timer (struct thread *t)
+ospf_spf_calculate_timer (struct thread *thread)
 {
+  struct ospf *ospf = THREAD_ARG (thread);
   struct route_table *new_table, *new_rtrs;
-  struct ospf *ospf;
-  /* struct ospf_area *area; */
   listnode node;
 
   if (IS_DEBUG_OSPF_EVENT)
     zlog_info ("SPF: Timer (SPF calculation expire)");
   
-  ospf = THREAD_ARG (t);
   ospf->t_spf_calc = NULL;
 
   /* Allocate new table tree. */
   new_table = route_table_init ();
   new_rtrs  = route_table_init ();
 
-  ospf_vl_unapprove ();
+  ospf_vl_unapprove (ospf);
 
   /* Calculate SPF for each area. */
   for (node = listhead (ospf->areas); node; node = nextnode (node))
     ospf_spf_calculate (node->data, new_table, new_rtrs);
 
-  ospf_vl_shut_unapproved ();
+  ospf_vl_shut_unapproved (ospf);
 
-  ospf_ia_routing (new_table, new_rtrs);
+  ospf_ia_routing (ospf, new_table, new_rtrs);
 
   ospf_prune_unreachable_networks (new_table);
   ospf_prune_unreachable_routers (new_rtrs);
@@ -1038,26 +1038,26 @@
   /* If new Router Route is installed,
      then schedule re-calculate External routes. */
   if (1)
-    ospf_ase_calculate_schedule ();
+    ospf_ase_calculate_schedule (ospf);
 
-  ospf_ase_calculate_timer_add ();
+  ospf_ase_calculate_timer_add (ospf);
 
   /* Update routing table. */
-  ospf_route_install (new_table);
+  ospf_route_install (ospf, new_table);
 
   /* Update ABR/ASBR routing table */
-  if (ospf_top->old_rtrs)
+  if (ospf->old_rtrs)
     {
       /* old_rtrs's node holds linked list of ospf_route. --kunihiro. */
-      /* ospf_route_delete (ospf_top->old_rtrs); */
-      ospf_rtrs_free (ospf_top->old_rtrs);
+      /* ospf_route_delete (ospf->old_rtrs); */
+      ospf_rtrs_free (ospf->old_rtrs);
     }
 
-  ospf_top->old_rtrs = ospf_top->new_rtrs;
-  ospf_top->new_rtrs = new_rtrs;
+  ospf->old_rtrs = ospf->new_rtrs;
+  ospf->new_rtrs = new_rtrs;
 
   if (OSPF_IS_ABR) 
-    ospf_abr_task (new_table, new_rtrs);
+    ospf_abr_task (ospf);
 
   if (IS_DEBUG_OSPF_EVENT)
     zlog_info ("SPF: calculation complete");
@@ -1068,7 +1068,7 @@
 /* Add schedule for SPF calculation.  To avoid frequenst SPF calc, we
    set timer for SPF calc. */
 void
-ospf_spf_calculate_schedule ()
+ospf_spf_calculate_schedule (struct ospf *ospf)
 {
   time_t ht, delay;
 
@@ -1076,34 +1076,34 @@
     zlog_info ("SPF: calculation timer scheduled");
 
   /* OSPF instance does not exist. */
-  if (!ospf_top)
+  if (ospf == NULL)
     return;
 
   /* SPF calculation timer is already scheduled. */
-  if (ospf_top->t_spf_calc)
+  if (ospf->t_spf_calc)
     {
       if (IS_DEBUG_OSPF_EVENT)
 	zlog_info ("SPF: calculation timer is already scheduled: %p",
-		   ospf_top->t_spf_calc);
+		   ospf->t_spf_calc);
       return;
     }
 
-  ht = time (NULL) - ospf_top->ts_spf;
+  ht = time (NULL) - ospf->ts_spf;
 
   /* Get SPF calculation delay time. */
-  if (ht < ospf_top->spf_holdtime)
+  if (ht < ospf->spf_holdtime)
     {
-      if (ospf_top->spf_holdtime - ht < ospf_top->spf_delay)
-	delay = ospf_top->spf_delay;
+      if (ospf->spf_holdtime - ht < ospf->spf_delay)
+	delay = ospf->spf_delay;
       else
-	delay = ospf_top->spf_holdtime - ht;
+	delay = ospf->spf_holdtime - ht;
     }
   else
-    delay = ospf_top->spf_delay;
+    delay = ospf->spf_delay;
 
   if (IS_DEBUG_OSPF_EVENT)
     zlog_info ("SPF: calculation timer delay = %ld", delay);
-  ospf_top->t_spf_calc =
-    thread_add_timer (master, ospf_spf_calculate_timer, ospf_top, delay);
+  ospf->t_spf_calc =
+    thread_add_timer (master, ospf_spf_calculate_timer, ospf, delay);
 }
 
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index accf7a8..fff6f65 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -199,8 +199,9 @@
        "router-id for the OSPF process\n"
        "OSPF router-id in IP address format\n")
 {
-  int ret;
+  struct ospf *ospf = vty->index;
   struct in_addr router_id;
+  int ret;
 
   ret = inet_aton (argv[0], &router_id);
   if (!ret)
@@ -209,11 +210,10 @@
       return CMD_WARNING;
     }
 
-  /* ospf_top->router_id = router_id; */
-  ospf_top->router_id_static = router_id;
+  ospf->router_id_static = router_id;
 
-  if (ospf_top->t_router_id_update == NULL)
-    ospf_top->t_router_id_update =
+  if (ospf->t_router_id_update == NULL)
+    ospf->t_router_id_update =
       thread_add_timer (master, ospf_router_id_update_timer, NULL,
 			OSPF_ROUTER_ID_UPDATE_DELAY);
 
@@ -233,9 +233,11 @@
        "OSPF specific commands\n"
        "router-id for the OSPF process\n")
 {
-  ospf_top->router_id_static.s_addr = 0;
+  struct ospf *ospf = vty->index;
 
-  ospf_router_id_update ();
+  ospf->router_id_static.s_addr = 0;
+
+  ospf_router_id_update (ospf);
 
   return CMD_SUCCESS;
 }
@@ -647,7 +649,7 @@
 }
 
 struct ospf_vl_data *
-ospf_find_vl_data (struct ospf_vl_config_data *vl_config)
+ospf_find_vl_data (struct ospf *ospf, struct ospf_vl_config_data *vl_config)
 {
   struct ospf_area *area;
   struct ospf_vl_data *vl_data;
@@ -664,7 +666,7 @@
                VTY_NEWLINE);
       return NULL;
     }
-  area = ospf_area_get (area_id, vl_config->format);
+  area = ospf_area_get (ospf, area_id, vl_config->format);
 
   if (area->external_routing != OSPF_AREA_DEFAULT)
     {
@@ -694,9 +696,9 @@
       vl_data = ospf_vl_data_new (area, vl_config->vl_peer);
       if (vl_data->vl_oi == NULL)
 	{
-	  vl_data->vl_oi = ospf_vl_new (vl_data);
-	  ospf_vl_add (vl_data);
-	  ospf_spf_calculate_schedule ();
+	  vl_data->vl_oi = ospf_vl_new (ospf, vl_data);
+	  ospf_vl_add (ospf, vl_data);
+	  ospf_spf_calculate_schedule (ospf);
 	}
     }
   return vl_data;
@@ -800,12 +802,12 @@
 
 /* The business end of all of the above */
 int
-ospf_vl_set (struct ospf_vl_config_data *vl_config)
+ospf_vl_set (struct ospf *ospf, struct ospf_vl_config_data *vl_config)
 {
   struct ospf_vl_data *vl_data;
   int ret;
 
-  vl_data = ospf_find_vl_data (vl_config);
+  vl_data = ospf_find_vl_data (ospf, vl_config);
   if (!vl_data)
     return CMD_WARNING;
   
@@ -872,6 +874,7 @@
        "area (A.B.C.D|<0-4294967295>) virtual-link A.B.C.D",
        VLINK_HELPSTR_IPADDR)
 {
+  struct ospf *ospf = vty->index;
   struct ospf_vl_config_data vl_config;
   char auth_key[OSPF_AUTH_SIMPLE_SIZE+1];
   char md5_key[OSPF_AUTH_MD5_SIZE+1]; 
@@ -900,7 +903,7 @@
     {
       /* Thats all folks! - BUGS B. strikes again!!!*/
 
-      return  ospf_vl_set (&vl_config);
+      return  ospf_vl_set (ospf, &vl_config);
     }
 
   /* Deal with other parameters */
@@ -996,7 +999,7 @@
 
   /* Action configuration */
 
-  return ospf_vl_set (&vl_config);
+  return ospf_vl_set (ospf, &vl_config);
 
 }
 
@@ -1006,6 +1009,7 @@
        NO_STR
        VLINK_HELPSTR_IPADDR)
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct ospf_vl_config_data vl_config;
   struct ospf_vl_data *vl_data = NULL;
@@ -1022,7 +1026,7 @@
       return CMD_WARNING;
     }
 
-  area = ospf_area_lookup_by_area_id (vl_config.area_id);
+  area = ospf_area_lookup_by_area_id (ospf, vl_config.area_id);
   if (!area)
     {
       vty_out (vty, "Area does not exist%s", VTY_NEWLINE);
@@ -1042,9 +1046,9 @@
       /* Basic VLink no command */
       /* Thats all folks! - BUGS B. strikes again!!!*/
       if ((vl_data = ospf_vl_lookup (area, vl_config.vl_peer)))
-	ospf_vl_delete (vl_data);
+	ospf_vl_delete (ospf, vl_data);
 
-      ospf_area_check_free (vl_config.area_id);
+      ospf_area_check_free (ospf, vl_config.area_id);
       
       return CMD_SUCCESS;
     }
@@ -1054,7 +1058,6 @@
   /* Deal with other parameters */
   for (i=2; i < argc; i++)
     {
-
       /* vty_out (vty, "argv[%d] - %s%s", i, argv[i], VTY_NEWLINE); */
 
       switch (argv[i][0])
@@ -1113,7 +1116,7 @@
 
   /* Action configuration */
 
-  return ospf_vl_set (&vl_config);
+  return ospf_vl_set (ospf, &vl_config);
 }
 
 ALIAS (area_vlink,
@@ -1320,6 +1323,7 @@
        "Enable shortcutting through the area\n"
        "Disable shortcutting through the area\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   int mode;
@@ -1327,7 +1331,7 @@
 
   VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[0]);
 
-  area = ospf_area_get (area_id, format);
+  area = ospf_area_get (ospf, area_id, format);
 
   if (strncmp (argv[1], "de", 2) == 0)
     mode = OSPF_SHORTCUT_DEFAULT;
@@ -1338,9 +1342,9 @@
   else
     return CMD_WARNING;
 
-  ospf_area_shortcut_set (area, mode);
+  ospf_area_shortcut_set (ospf, area, mode);
 
-  if (ospf_top->abr_type != OSPF_ABR_SHORTCUT)
+  if (ospf->abr_type != OSPF_ABR_SHORTCUT)
     vty_out (vty, "Shortcut area setting will take effect "
 	     "only when the router is configured as Shortcut ABR%s",
 	     VTY_NEWLINE);
@@ -1359,17 +1363,18 @@
        "Deconfigure enabled shortcutting through the area\n"
        "Deconfigure disabled shortcutting through the area\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   int format;
 
   VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[0]);
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (!area)
     return CMD_SUCCESS;
 
-  ospf_area_shortcut_unset (area);
+  ospf_area_shortcut_unset (ospf, area);
 
   return CMD_SUCCESS;
 }
@@ -1617,6 +1622,7 @@
        "Set the summary-default cost of a NSSA or stub area\n"
        "Stub's advertised default summary cost\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   u_int32_t cost;
@@ -1625,7 +1631,7 @@
   VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[0]);
   VTY_GET_INTEGER_RANGE ("stub default cost", cost, argv[1], 0, 16777215);
 
-  area = ospf_area_get (area_id, format);
+  area = ospf_area_get (ospf, area_id, format);
 
   if (area->external_routing == OSPF_AREA_DEFAULT)
     {
@@ -1648,6 +1654,7 @@
        "Set the summary-default cost of a NSSA or stub area\n"
        "Stub's advertised default summary cost\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   u_int32_t cost;
@@ -1656,7 +1663,7 @@
   VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[0]);
   VTY_GET_INTEGER_RANGE ("stub default cost", cost, argv[1], 0, 16777215);
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return CMD_SUCCESS;
 
@@ -1668,7 +1675,7 @@
 
   area->default_cost = 1;
 
-  ospf_area_check_free (area_id);
+  ospf_area_check_free (ospf, area_id);
 
   return CMD_SUCCESS;
 }
@@ -1682,14 +1689,15 @@
        "Set the filter for networks announced to other areas\n"
        "Name of the access-list\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   int format;
 
   VTY_GET_OSPF_AREA_ID_NO_BB ("export-list", area_id, format, argv[0]);
 
-  area = ospf_area_get (area_id, format);
-  ospf_area_export_list_set (area, argv[1]);
+  area = ospf_area_get (ospf, area_id, format);
+  ospf_area_export_list_set (ospf, area, argv[1]);
 
   return CMD_SUCCESS;
 }
@@ -1704,17 +1712,18 @@
        "Unset the filter for networks announced to other areas\n"
        "Name of the access-list\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   int format;
 
   VTY_GET_OSPF_AREA_ID_NO_BB ("export-list", area_id, format, argv[0]);
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return CMD_SUCCESS;
 
-  ospf_area_export_list_unset (area);
+  ospf_area_export_list_unset (ospf, area);
 
   return CMD_SUCCESS;
 }
@@ -1729,14 +1738,15 @@
        "Set the filter for networks from other areas announced to the specified one\n"
        "Name of the access-list\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   int format;
 
   VTY_GET_OSPF_AREA_ID_NO_BB ("import-list", area_id, format, argv[0]);
 
-  area = ospf_area_get (area_id, format);
-  ospf_area_import_list_set (area, argv[1]);
+  area = ospf_area_get (ospf, area_id, format);
+  ospf_area_import_list_set (ospf, area, argv[1]);
 
   return CMD_SUCCESS;
 }
@@ -1751,16 +1761,17 @@
        "Unset the filter for networks announced to other areas\n"
        "Name of the access-list\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   int format;
 
   VTY_GET_OSPF_AREA_ID_NO_BB ("import-list", area_id, format, argv[0]);
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return CMD_SUCCESS;
 
-  ospf_area_import_list_unset (area);
+  ospf_area_import_list_unset (ospf, area);
 
   return CMD_SUCCESS;
 }
@@ -1777,6 +1788,7 @@
        "Filter networks sent to this area\n"
        "Filter networks sent from this area\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   struct prefix_list *plist;
@@ -1784,7 +1796,7 @@
 
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
-  area = ospf_area_get (area_id, format);
+  area = ospf_area_get (ospf, area_id, format);
   plist = prefix_list_lookup (AFI_IP, argv[1]);
   if (strncmp (argv[2], "in", 2) == 0)
     {
@@ -1793,7 +1805,7 @@
 	free (PREFIX_NAME_IN (area));
 
       PREFIX_NAME_IN (area) = strdup (argv[1]);
-      ospf_schedule_abr_task ();
+      ospf_schedule_abr_task (ospf);
     }
   else
     {
@@ -1802,7 +1814,7 @@
 	free (PREFIX_NAME_OUT (area));
 
       PREFIX_NAME_OUT (area) = strdup (argv[1]);
-      ospf_schedule_abr_task ();
+      ospf_schedule_abr_task (ospf);
     }
 
   return CMD_SUCCESS;
@@ -1821,6 +1833,7 @@
        "Filter networks sent to this area\n"
        "Filter networks sent from this area\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   struct prefix_list *plist;
@@ -1828,7 +1841,7 @@
 
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   plist = prefix_list_lookup (AFI_IP, argv[1]);
   if (strncmp (argv[2], "in", 2) == 0)
     {
@@ -1842,7 +1855,7 @@
 
       PREFIX_NAME_IN (area) = NULL;
 
-      ospf_schedule_abr_task ();
+      ospf_schedule_abr_task (ospf);
     }
   else
     {
@@ -1856,7 +1869,7 @@
 
       PREFIX_NAME_OUT (area) = NULL;
 
-      ospf_schedule_abr_task ();
+      ospf_schedule_abr_task (ospf);
     }
 
   return CMD_SUCCESS;
@@ -1870,13 +1883,14 @@
        "Enable authentication\n"
        "Use message-digest authentication\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   int format;
 
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
-  area = ospf_area_get (area_id, format);
+  area = ospf_area_get (ospf, area_id, format);
   area->auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
 
   return CMD_SUCCESS;
@@ -1890,13 +1904,14 @@
        "OSPF area ID as a decimal value\n"
        "Enable authentication\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   int format;
 
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
-  area = ospf_area_get (area_id, format);
+  area = ospf_area_get (ospf, area_id, format);
   area->auth_type = OSPF_AUTH_SIMPLE;
 
   return CMD_SUCCESS;
@@ -1911,19 +1926,20 @@
        "OSPF area ID as a decimal value\n"
        "Enable authentication\n")
 {
+  struct ospf *ospf = vty->index;
   struct ospf_area *area;
   struct in_addr area_id;
   int format;
 
   VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]);
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return CMD_SUCCESS;
 
   area->auth_type = OSPF_AUTH_NULL;
 
-  ospf_area_check_free (area_id);
+  ospf_area_check_free (ospf, area_id);
   
   return CMD_SUCCESS;
 }
@@ -1939,6 +1955,7 @@
        "Shortcut ABR\n"
        "Standard behavior (RFC2328)\n")
 {
+  struct ospf *ospf = vty->index;
   u_char abr_type = OSPF_ABR_UNKNOWN;
 
   if (strncmp (argv[0], "c", 1) == 0)
@@ -1953,10 +1970,10 @@
     return CMD_WARNING;
 
   /* If ABR type value is changed, schedule ABR task. */
-  if (ospf_top->abr_type != abr_type)
+  if (ospf->abr_type != abr_type)
     {
-      ospf_top->abr_type = abr_type;
-      ospf_schedule_abr_task ();
+      ospf->abr_type = abr_type;
+      ospf_schedule_abr_task (ospf);
     }
 
   return CMD_SUCCESS;
@@ -1972,6 +1989,7 @@
        "Alternative ABR, IBM implementation\n"
        "Shortcut ABR\n")
 {
+  struct ospf *ospf = vty->index;
   u_char abr_type = OSPF_ABR_UNKNOWN;
 
   if (strncmp (argv[0], "c", 1) == 0)
@@ -1984,10 +2002,10 @@
     return CMD_WARNING;
 
   /* If ABR type value is changed, schedule ABR task. */
-  if (ospf_top->abr_type == abr_type)
+  if (ospf->abr_type == abr_type)
     {
-      ospf_top->abr_type = OSPF_ABR_STAND;
-      ospf_schedule_abr_task ();
+      ospf->abr_type = OSPF_ABR_STAND;
+      ospf_schedule_abr_task (ospf);
     }
 
   return CMD_SUCCESS;
@@ -2004,7 +2022,7 @@
   if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
     {
       SET_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE);
-      ospf_spf_calculate_schedule ();
+      ospf_spf_calculate_schedule (ospf);
     }
   return CMD_SUCCESS;
 }
@@ -2021,7 +2039,7 @@
   if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
     {
       UNSET_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE);
-      ospf_spf_calculate_schedule ();
+      ospf_spf_calculate_schedule (ospf);
     }
   return CMD_SUCCESS;
 }
@@ -2065,8 +2083,10 @@
        "Adjust routing timers\n"
        "OSPF SPF timers\n")
 {
-  ospf_top->spf_delay = OSPF_SPF_DELAY_DEFAULT;
-  ospf_top->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
+  struct ospf *ospf = vty->index;
+
+  ospf->spf_delay = OSPF_SPF_DELAY_DEFAULT;
+  ospf->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
 
   return CMD_SUCCESS;
 }
@@ -2259,6 +2279,7 @@
        "Use reference bandwidth method to assign OSPF cost\n"
        "The reference bandwidth in terms of Mbits per second\n")
 {
+  struct ospf *ospf = vty->index;
   u_int32_t refbw;
   listnode node;
 
@@ -2270,14 +2291,14 @@
     }
 
   /* If reference bandwidth is changed. */
-  if ((refbw * 1000) == ospf_top->ref_bandwidth)
+  if ((refbw * 1000) == ospf->ref_bandwidth)
     return CMD_SUCCESS;
   
-  ospf_top->ref_bandwidth = refbw * 1000;
+  ospf->ref_bandwidth = refbw * 1000;
   vty_out (vty, "%% OSPF: Reference bandwidth is changed.%s", VTY_NEWLINE);
   vty_out (vty, "        Please ensure reference bandwidth is consistent across all routers%s", VTY_NEWLINE);
       
-  for (node = listhead (ospf_top->iflist); node; nextnode (node))
+  for (node = listhead (ospf->iflist); node; nextnode (node))
       ospf_if_recalculate_output_cost (getdata (node));
   
   return CMD_SUCCESS;
@@ -2290,61 +2311,22 @@
        "Calculate OSPF interface cost according to bandwidth\n"
        "Use reference bandwidth method to assign OSPF cost\n")
 {
+  struct ospf *ospf = vty->index;
   listnode node;
 
-  if (ospf_top->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH)
+  if (ospf->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH)
     return CMD_SUCCESS;
   
-  ospf_top->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
+  ospf->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
   vty_out (vty, "%% OSPF: Reference bandwidth is changed.%s", VTY_NEWLINE);
   vty_out (vty, "        Please ensure reference bandwidth is consistent across all routers%s", VTY_NEWLINE);
 
-  
-    for (node = listhead (ospf_top->iflist); node; nextnode (node))
+    for (node = listhead (ospf->iflist); node; nextnode (node))
       ospf_if_recalculate_output_cost (getdata (node));
       
   return CMD_SUCCESS;
 }
 
-
-DEFUN (clear_ip_ospf_neighbor,
-       clear_ip_ospf_neighbor_cmd,
-       "clear ip ospf neighbor A.B.C.D",
-       "Reset functions\n"
-       "IP\n"
-       "Clear OSPF\n"
-       "Neighbor list\n"
-       "Neighbor ID\n")
-{
-  listnode node;
-  struct ospf_neighbor *nbr;
-  struct in_addr router_id;
-  int ret;
-
-  ret = inet_aton (argv[0], &router_id);
-  if (!ret)
-    {
-      vty_out (vty, "Please specify Neighbor ID by A.B.C.D%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
-    {
-      struct ospf_interface *oi = getdata (node);
-
-      nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &router_id);
-
-      if (nbr)
-	{
-	  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
-	  vty_out (vty, "clear neighbor %s%s", argv[0], VTY_NEWLINE);
-	  break;
-	}
-    }
-
-  return CMD_SUCCESS;
-}
-
 char *ospf_abr_type_descr_str[] = 
 {
   "Unknown",
@@ -2453,9 +2435,10 @@
 {
   listnode node;
   struct ospf_area * area;
+  struct ospf *ospf = ospf_top;
 
   /* Check OSPF is enable. */
-  if (ospf_top == NULL)
+  if (ospf == NULL)
     {
       vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
       return CMD_SUCCESS;
@@ -2463,51 +2446,51 @@
 
   /* Show Router ID. */
   vty_out (vty, " OSPF Routing Process, Router ID: %s%s",
-           inet_ntoa (ospf_top->router_id),
+           inet_ntoa (ospf->router_id),
            VTY_NEWLINE);
 
   /* Show capability. */
   vty_out (vty, " Supports only single TOS (TOS0) routes%s", VTY_NEWLINE);
   vty_out (vty, " This implementation conforms to RFC2328%s", VTY_NEWLINE);
   vty_out (vty, " RFC1583Compatibility flag is %s%s",
-	   CHECK_FLAG (ospf_top->config, OSPF_RFC1583_COMPATIBLE) ?
+	   CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE) ?
 	   "enabled" : "disabled", VTY_NEWLINE);
 #ifdef HAVE_OPAQUE_LSA
   vty_out (vty, " OpaqueCapability flag is %s%s%s",
-	   CHECK_FLAG (ospf_top->config, OSPF_OPAQUE_CAPABLE) ?
+	   CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE) ?
            "enabled" : "disabled",
-           IS_OPAQUE_LSA_ORIGINATION_BLOCKED (ospf_top->opaque) ?
+           IS_OPAQUE_LSA_ORIGINATION_BLOCKED (ospf->opaque) ?
            " (origination blocked)" : "",
            VTY_NEWLINE);
 #endif /* HAVE_OPAQUE_LSA */
 
   /* Show SPF timers. */
   vty_out (vty, " SPF schedule delay %d secs, Hold time between two SPFs %d secs%s",
-	   ospf_top->spf_delay, ospf_top->spf_holdtime, VTY_NEWLINE);
+	   ospf->spf_delay, ospf->spf_holdtime, VTY_NEWLINE);
 
   /* Show refresh parameters. */
   vty_out (vty, " Refresh timer %d secs%s",
-	   ospf_top->lsa_refresh_interval, VTY_NEWLINE);
+	   ospf->lsa_refresh_interval, VTY_NEWLINE);
 	   
   /* Show ABR/ASBR flags. */
-  if (CHECK_FLAG (ospf_top->flags, OSPF_FLAG_ABR))
+  if (CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
     vty_out (vty, " This router is an ABR, ABR type is: %s%s",
-             ospf_abr_type_descr_str[ospf_top->abr_type], VTY_NEWLINE);
+             ospf_abr_type_descr_str[ospf->abr_type], VTY_NEWLINE);
 
-  if (CHECK_FLAG (ospf_top->flags, OSPF_FLAG_ASBR))
+  if (CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
     vty_out (vty, " This router is an ASBR "
              "(injecting external routing information)%s", VTY_NEWLINE);
 
   /* Show Number of AS-external-LSAs. */
   vty_out (vty, " Number of external LSA %ld%s",
-	   ospf_lsdb_count_all (ospf_top->lsdb), VTY_NEWLINE);
+	   ospf_lsdb_count_all (ospf->lsdb), VTY_NEWLINE);
 
   /* Show number of areas attached. */
   vty_out (vty, " Number of areas attached to this router: %d%s%s",
-           listcount (ospf_top->areas), VTY_NEWLINE, VTY_NEWLINE);
+           listcount (ospf->areas), VTY_NEWLINE, VTY_NEWLINE);
 
   /* Show each area status. */
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     if ((area = getdata (node)) != NULL)
       show_ip_ospf_area (vty, area);
 
@@ -2516,7 +2499,8 @@
 
 
 void
-show_ip_ospf_interface_sub (struct vty *vty, struct interface *ifp)
+show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf,
+			    struct interface *ifp)
 {
   struct ospf_neighbor *nbr;
   int oi_count;
@@ -2563,7 +2547,7 @@
 	       VTY_NEWLINE);
 
       vty_out (vty, "  Router ID %s, Network Type %s, Cost: %d%s",
-	       inet_ntoa (ospf_top->router_id), ospf_network_type_str[oi->type],
+	       inet_ntoa (ospf->router_id), ospf_network_type_str[oi->type],
 	       oi->output_cost, VTY_NEWLINE);
 
       vty_out (vty, "  Transmit Delay is %d sec, State %s, Priority %d%s",
@@ -2619,7 +2603,7 @@
 	vty_out (vty, "    No Hellos (Passive interface)%s", VTY_NEWLINE);
       
       vty_out (vty, "  Neighbor Count is %d, Adjacent neighbor count is %d%s",
-	       ospf_nbr_count (oi->nbrs, 0), ospf_nbr_count (oi->nbrs, NSM_Full),
+	       ospf_nbr_count (oi, 0), ospf_nbr_count (oi, NSM_Full),
 	       VTY_NEWLINE);
     }
 }
@@ -2634,19 +2618,20 @@
        "Interface name\n")
 {
   struct interface *ifp;
+  struct ospf *ospf = ospf_top;
   listnode node;
 
   /* Show All Interfaces. */
   if (argc == 0)
     for (node = listhead (iflist); node; nextnode (node))
-      show_ip_ospf_interface_sub (vty, node->data);
+      show_ip_ospf_interface_sub (vty, ospf, node->data);
   /* Interface name is specified. */
   else
     {
       if ((ifp = if_lookup_by_name (argv[0])) == NULL)
         vty_out (vty, "No such interface name%s", VTY_NEWLINE);
       else
-        show_ip_ospf_interface_sub (vty, ifp);
+        show_ip_ospf_interface_sub (vty, ospf, ifp);
     }
 
   return CMD_SUCCESS;
@@ -2693,9 +2678,10 @@
        "OSPF information\n"
        "Neighbor list\n")
 {
+  struct ospf *ospf = ospf_top;
   listnode node;
 
-  if (!ospf_top)
+  if (ospf == NULL)
     {
       vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
       return CMD_SUCCESS;
@@ -2706,7 +2692,7 @@
            "Time   Address         Interface           RXmtL "
            "RqstL DBsmL%s", VTY_NEWLINE, VTY_NEWLINE);
 
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
       show_ip_ospf_neighbor_sub (vty, getdata (node));
 
   return CMD_SUCCESS;
@@ -2721,9 +2707,10 @@
        "Neighbor list\n"
        "include down status neighbor\n")
 {
+  struct ospf *ospf = vty->index;
   listnode node;
 
-  if (!ospf_top)
+  if (ospf == NULL)
     {
       vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
       return CMD_SUCCESS;
@@ -2734,7 +2721,7 @@
            "Time   Address         Interface           RXmtL "
            "RqstL DBsmL%s", VTY_NEWLINE, VTY_NEWLINE);
 
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
     {
       struct ospf_interface *oi = getdata (node);
       listnode nbr_node;
@@ -2772,11 +2759,12 @@
        "Neighbor list\n"
        "Interface name\n")
 {
+  struct ospf *ospf = ospf_top;
   struct ospf_interface *oi;
   struct in_addr addr;
   int ret;
   
-  if (!ospf_top)
+  if (ospf == NULL)
     {
       vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE);
       return CMD_SUCCESS;
@@ -2790,7 +2778,7 @@
       return CMD_WARNING;
     }
 
-  if ((oi = ospf_if_is_configured (&addr)) == NULL)
+  if ((oi = ospf_if_is_configured (ospf, &addr)) == NULL)
     vty_out (vty, "No such interface address%s", VTY_NEWLINE);
   else
     {
@@ -2902,6 +2890,7 @@
        "Neighbor list\n"
        "Neighbor ID\n")
 {
+  struct ospf *ospf = ospf_top;
   listnode node;
   struct ospf_neighbor *nbr;
   struct in_addr router_id;
@@ -2914,7 +2903,7 @@
       return CMD_WARNING;
     }
 
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
     {
       struct ospf_interface *oi = getdata (node);
 
@@ -2938,12 +2927,13 @@
        "Neighbor list\n"
        "detail of all neighbors\n")
 {
+  struct ospf *ospf = ospf_top;
   listnode node;
 
-  if (!ospf_top)
+  if (ospf == NULL)
     return CMD_SUCCESS;
 
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
     {
       struct ospf_interface *oi = getdata (node);
       struct route_node *rn;
@@ -2969,12 +2959,13 @@
        "detail of all neighbors\n"
        "include down status neighbor\n")
 {
+  struct ospf *ospf = ospf_top;
   listnode node;
 
-  if (!ospf_top)
+  if (ospf == NULL)
     return CMD_SUCCESS;
 
-  for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+  for (node = listhead (ospf->oiflist); node; nextnode (node))
     {
       struct ospf_interface *oi = getdata (node);
       struct route_node *rn;
@@ -3025,7 +3016,10 @@
       return CMD_WARNING;
     }
 
-  if ((oi = ospf_if_is_configured (&addr)) == NULL)
+  if (ospf_top == NULL)
+    return CMD_WARNING;
+
+  if ((oi = ospf_if_is_configured (ospf_top, &addr)) == NULL)
     vty_out (vty, "No such interface address%s", VTY_NEWLINE);
   else
     {
@@ -3203,7 +3197,7 @@
   "(null)",
   "Neighboring Router ID",
   "Designated Router address",
-  "Network/subnet number",
+  "Net",
   "Neighboring Router ID",
 };
 
@@ -3509,6 +3503,7 @@
 show_lsa_detail (struct vty *vty, int type,
 		 struct in_addr *id, struct in_addr *adv_router)
 {
+  struct ospf *ospf = ospf_top;
   listnode node;
 
   switch (type)
@@ -3520,10 +3515,10 @@
       vty_out (vty, "                %s %s%s",
                show_database_desc[type],
                VTY_NEWLINE, VTY_NEWLINE);
-      show_lsa_detail_proc (vty, AS_LSDB (ospf_top, type), id, adv_router);
+      show_lsa_detail_proc (vty, AS_LSDB (ospf, type), id, adv_router);
       break;
     default:
-      for (node = listhead (ospf_top->areas); node; nextnode (node))
+      for (node = listhead (ospf->areas); node; nextnode (node))
         {
           struct ospf_area *area = node->data;
           vty_out (vty, "%s                %s (Area %s)%s%s",
@@ -3560,6 +3555,7 @@
 show_lsa_detail_adv_router (struct vty *vty, int type,
 			    struct in_addr *adv_router)
 {
+  struct ospf *ospf = ospf_top;
   listnode node;
 
   switch (type)
@@ -3571,11 +3567,11 @@
       vty_out (vty, "                %s %s%s",
                show_database_desc[type],
                VTY_NEWLINE, VTY_NEWLINE);
-      show_lsa_detail_adv_router_proc (vty, AS_LSDB (ospf_top, type),
+      show_lsa_detail_adv_router_proc (vty, AS_LSDB (ospf, type),
                                        adv_router);
       break;
     default:
-      for (node = listhead (ospf_top->areas); node; nextnode (node))
+      for (node = listhead (ospf->areas); node; nextnode (node))
         {
           struct ospf_area *area = node->data;
           vty_out (vty, "%s                %s (Area %s)%s%s",
@@ -3591,10 +3587,11 @@
 void
 show_ip_ospf_database_summary (struct vty *vty, int self)
 {
+  struct ospf *ospf = ospf_top;
   listnode node;
   int type;
 
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     {
       struct ospf_area *area = node->data;
       for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++)
@@ -3637,15 +3634,15 @@
           default:
             continue;
         }
-      if (ospf_lsdb_count_self (ospf_top->lsdb, type) ||
-         (!self && ospf_lsdb_count (ospf_top->lsdb, type)))
+      if (ospf_lsdb_count_self (ospf->lsdb, type) ||
+         (!self && ospf_lsdb_count (ospf->lsdb, type)))
         {
           vty_out (vty, "                %s%s%s",
 	       show_database_desc[type],
 	       VTY_NEWLINE, VTY_NEWLINE);
           vty_out (vty, "%s%s", show_database_header[type],
 	       VTY_NEWLINE);
-          foreach_lsa (AS_LSDB (ospf_top, type), vty, self, show_lsa_summary);
+          foreach_lsa (AS_LSDB (ospf, type), vty, self, show_lsa_summary);
           vty_out (vty, "%s", VTY_NEWLINE);
         }
     }
@@ -3656,13 +3653,14 @@
 void
 show_ip_ospf_database_maxage (struct vty *vty)
 {
+  struct ospf *ospf = ospf_top;
   listnode node;
   struct ospf_lsa *lsa;
 
   vty_out (vty, "%s                MaxAge Link States:%s%s",
            VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
 
-  for (node = listhead (ospf_top->maxage_lsa); node; nextnode (node))
+  for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
     if ((lsa = node->data) != NULL)
       {
 	vty_out (vty, "Link type: %d%s", lsa->data->type, VTY_NEWLINE);
@@ -3719,14 +3717,15 @@
        "OSPF information\n"
        "Database summary\n")
 {
+  struct ospf *ospf = ospf_top;
   int type, ret;
   struct in_addr id, adv_router;
 
-  if (ospf_top == NULL)
+  if (ospf == NULL)
     return CMD_SUCCESS;
 
   vty_out (vty, "%s       OSPF Router with ID (%s)%s%s", VTY_NEWLINE,
-           inet_ntoa (ospf_top->router_id), VTY_NEWLINE, VTY_NEWLINE);
+           inet_ntoa (ospf->router_id), VTY_NEWLINE, VTY_NEWLINE);
 
   /* Show all LSA. */
   if (argc == 0)
@@ -3787,7 +3786,7 @@
       else if (argc == 3)
 	{
 	  if (strncmp (argv[2], "s", 1) == 0)
-	    adv_router = ospf_top->router_id;
+	    adv_router = ospf->router_id;
 	  else
 	    {
 	      ret = inet_aton (argv[2], &adv_router);
@@ -3857,14 +3856,15 @@
        "Advertising Router link states\n"
        "Advertising Router (as an IP address)\n")
 {
+  struct ospf *ospf = ospf_top;
   int type, ret;
   struct in_addr adv_router;
 
-  if (ospf_top == NULL)
+  if (ospf == NULL)
     return CMD_SUCCESS;
 
   vty_out (vty, "%s       OSPF Router with ID (%s)%s%s", VTY_NEWLINE,
-           inet_ntoa (ospf_top->router_id), VTY_NEWLINE, VTY_NEWLINE);
+           inet_ntoa (ospf->router_id), VTY_NEWLINE, VTY_NEWLINE);
 
   if (argc != 2)
     return CMD_WARNING;
@@ -3897,7 +3897,7 @@
 
   /* `show ip ospf database LSA adv-router ADV_ROUTER'. */
   if (strncmp (argv[1], "s", 1) == 0)
-    adv_router = ospf_top->router_id;
+    adv_router = ospf->router_id;
   else
     {
       ret = inet_aton (argv[1], &adv_router);
@@ -4488,6 +4488,7 @@
   struct ospf_if_params *params;
   struct ospf_interface *oi;
   struct route_node *rn;
+  struct ospf *ospf = ospf_top;
       
   params = IF_DEF_PARAMS (ifp);
 
@@ -4520,9 +4521,12 @@
   /* Update timer values in neighbor structure. */
   if (argc == 2)
     {
-      oi = ospf_if_lookup_by_local_addr (ifp, addr);
-      if (oi)
-	ospf_nbr_timer_update (oi);
+      if (ospf)
+	{
+	  oi = ospf_if_lookup_by_local_addr (ospf, ifp, addr);
+	  if (oi)
+	    ospf_nbr_timer_update (oi);
+	}
     }
   else
     {
@@ -4564,6 +4568,7 @@
   struct ospf_if_params *params;
   struct ospf_interface *oi;
   struct route_node *rn;
+  struct ospf *ospf = ospf_top;
   
   ifp = vty->index;
   params = IF_DEF_PARAMS (ifp);
@@ -4595,9 +4600,12 @@
   /* Update timer values in neighbor structure. */
   if (argc == 1)
     {
-      oi = ospf_if_lookup_by_local_addr (ifp, addr);
-      if (oi)
-	ospf_nbr_timer_update (oi);
+      if (ospf)
+	{
+	  oi = ospf_if_lookup_by_local_addr (ospf, ifp, addr);
+	  if (oi)
+	    ospf_nbr_timer_update (oi);
+	}
     }
   else
     {
@@ -5515,13 +5523,14 @@
        "Routing Information Protocol (RIP)\n"
        "Border Gateway Protocol (BGP)\n")
 {
+  struct ospf *ospf = vty->index;
   int source;
 
   /* Get distribute source. */
   if (!str2distribute_source (argv[1], &source))
     return CMD_WARNING;
 
-  return ospf_distribute_list_out_set (source, argv[0]);
+  return ospf_distribute_list_out_set (ospf, source, argv[0]);
 }
 
 DEFUN (no_ospf_distribute_list_out,
@@ -5537,12 +5546,13 @@
        "Routing Information Protocol (RIP)\n"
        "Border Gateway Protocol (BGP)\n")
 {
+  struct ospf *ospf = vty->index;
   int source;
 
   if (!str2distribute_source (argv[1], &source))
     return CMD_WARNING;
 
-  return ospf_distribute_list_out_unset (source, argv[0]);
+  return ospf_distribute_list_out_unset (ospf, source, argv[0]);
 }
 
 /* Default information originate. */
@@ -5929,6 +5939,7 @@
        "Control distribution of default information\n"
        "Distribute a default route\n")
 {
+  struct ospf *ospf = vty->index;
   struct prefix_ipv4 p;
   struct in_addr nexthop;
     
@@ -5936,7 +5947,7 @@
   p.prefix.s_addr = 0;
   p.prefixlen = 0;
 
-  ospf_external_lsa_flush (DEFAULT_ROUTE, &p, 0, nexthop);
+  ospf_external_lsa_flush (ospf, DEFAULT_ROUTE, &p, 0, nexthop);
 
   if (EXTERNAL_INFO (DEFAULT_ROUTE)) {
     ospf_external_info_delete (DEFAULT_ROUTE, p);
@@ -5954,12 +5965,13 @@
        "Set metric of redistributed routes\n"
        "Default metric\n")
 {
+  struct ospf *ospf = vty->index;
   int metric = -1;
 
   if (!str2metric (argv[0], &metric))
     return CMD_WARNING;
 
-  ospf_top->default_metric = metric;
+  ospf->default_metric = metric;
 
   return CMD_SUCCESS;
 }
@@ -5970,7 +5982,10 @@
        NO_STR
        "Set metric of redistributed routes\n")
 {
-  ospf_top->default_metric = -1;
+  struct ospf *ospf = vty->index;
+
+  ospf->default_metric = -1;
+
   return CMD_SUCCESS;
 }
 
@@ -5987,7 +6002,10 @@
        "Define an administrative distance\n"
        "OSPF Administrative distance\n")
 {
-  ospf_top->distance_all = atoi (argv[0]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_all = atoi (argv[0]);
+
   return CMD_SUCCESS;
 }
 
@@ -5998,7 +6016,10 @@
        "Define an administrative distance\n"
        "OSPF Administrative distance\n")
 {
-  ospf_top->distance_all = 0;
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_all = 0;
+
   return CMD_SUCCESS;
 }
 
@@ -6010,9 +6031,12 @@
        "OSPF Administrative distance\n"
        "OSPF Distance\n")
 {
-  ospf_top->distance_intra = 0;
-  ospf_top->distance_inter = 0;
-  ospf_top->distance_external = 0;
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_intra = 0;
+  ospf->distance_inter = 0;
+  ospf->distance_external = 0;
+
   return CMD_SUCCESS;
 }
 
@@ -6024,7 +6048,10 @@
        "Intra-area routes\n"
        "Distance for intra-area routes\n")
 {
-  ospf_top->distance_intra = atoi (argv[0]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_intra = atoi (argv[0]);
+
   return CMD_SUCCESS;
 }
 
@@ -6038,8 +6065,11 @@
        "Inter-area routes\n"
        "Distance for inter-area routes\n")
 {
-  ospf_top->distance_intra = atoi (argv[0]);
-  ospf_top->distance_inter = atoi (argv[1]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_intra = atoi (argv[0]);
+  ospf->distance_inter = atoi (argv[1]);
+
   return CMD_SUCCESS;
 }
 
@@ -6053,8 +6083,11 @@
        "External routes\n"
        "Distance for external routes\n")
 {
-  ospf_top->distance_intra = atoi (argv[0]);
-  ospf_top->distance_external = atoi (argv[1]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_intra = atoi (argv[0]);
+  ospf->distance_external = atoi (argv[1]);
+
   return CMD_SUCCESS;
 }
 
@@ -6070,9 +6103,12 @@
        "External routes\n"
        "Distance for external routes\n")
 {
-  ospf_top->distance_intra = atoi (argv[0]);
-  ospf_top->distance_inter = atoi (argv[1]);
-  ospf_top->distance_external = atoi (argv[2]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_intra = atoi (argv[0]);
+  ospf->distance_inter = atoi (argv[1]);
+  ospf->distance_external = atoi (argv[2]);
+
   return CMD_SUCCESS;
 }
 
@@ -6088,9 +6124,12 @@
        "Inter-area routes\n"
        "Distance for inter-area routes\n")
 {
-  ospf_top->distance_intra = atoi (argv[0]);
-  ospf_top->distance_external = atoi (argv[1]);
-  ospf_top->distance_inter = atoi (argv[2]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_intra = atoi (argv[0]);
+  ospf->distance_external = atoi (argv[1]);
+  ospf->distance_inter = atoi (argv[2]);
+
   return CMD_SUCCESS;
 }
 
@@ -6102,7 +6141,10 @@
        "Inter-area routes\n"
        "Distance for inter-area routes\n")
 {
-  ospf_top->distance_inter = atoi (argv[0]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_inter = atoi (argv[0]);
+
   return CMD_SUCCESS;
 }
 
@@ -6116,8 +6158,11 @@
        "Intra-area routes\n"
        "Distance for intra-area routes\n")
 {
-  ospf_top->distance_inter = atoi (argv[0]);
-  ospf_top->distance_intra = atoi (argv[1]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_inter = atoi (argv[0]);
+  ospf->distance_intra = atoi (argv[1]);
+
   return CMD_SUCCESS;
 }
 
@@ -6131,8 +6176,11 @@
        "External routes\n"
        "Distance for external routes\n")
 {
-  ospf_top->distance_inter = atoi (argv[0]);
-  ospf_top->distance_external = atoi (argv[1]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_inter = atoi (argv[0]);
+  ospf->distance_external = atoi (argv[1]);
+
   return CMD_SUCCESS;
 }
 
@@ -6148,9 +6196,12 @@
        "External routes\n"
        "Distance for external routes\n")
 {
-  ospf_top->distance_inter = atoi (argv[0]);
-  ospf_top->distance_intra = atoi (argv[1]);
-  ospf_top->distance_external = atoi (argv[2]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_inter = atoi (argv[0]);
+  ospf->distance_intra = atoi (argv[1]);
+  ospf->distance_external = atoi (argv[2]);
+
   return CMD_SUCCESS;
 }
 
@@ -6166,9 +6217,12 @@
        "Intra-area routes\n"
        "Distance for intra-area routes\n")
 {
-  ospf_top->distance_inter = atoi (argv[0]);
-  ospf_top->distance_external = atoi (argv[1]);
-  ospf_top->distance_intra = atoi (argv[2]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_inter = atoi (argv[0]);
+  ospf->distance_external = atoi (argv[1]);
+  ospf->distance_intra = atoi (argv[2]);
+
   return CMD_SUCCESS;
 }
 
@@ -6180,7 +6234,10 @@
        "External routes\n"
        "Distance for external routes\n")
 {
-  ospf_top->distance_external = atoi (argv[0]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_external = atoi (argv[0]);
+
   return CMD_SUCCESS;
 }
 
@@ -6194,8 +6251,11 @@
        "Intra-area routes\n"
        "Distance for intra-area routes\n")
 {
-  ospf_top->distance_external = atoi (argv[0]);
-  ospf_top->distance_intra = atoi (argv[1]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_external = atoi (argv[0]);
+  ospf->distance_intra = atoi (argv[1]);
+
   return CMD_SUCCESS;
 }
 
@@ -6209,8 +6269,11 @@
        "Inter-area routes\n"
        "Distance for inter-area routes\n")
 {
-  ospf_top->distance_external = atoi (argv[0]);
-  ospf_top->distance_inter = atoi (argv[1]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_external = atoi (argv[0]);
+  ospf->distance_inter = atoi (argv[1]);
+
   return CMD_SUCCESS;
 }
 
@@ -6226,9 +6289,12 @@
        "Inter-area routes\n"
        "Distance for inter-area routes\n")
 {
-  ospf_top->distance_external = atoi (argv[0]);
-  ospf_top->distance_intra = atoi (argv[1]);
-  ospf_top->distance_inter = atoi (argv[2]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_external = atoi (argv[0]);
+  ospf->distance_intra = atoi (argv[1]);
+  ospf->distance_inter = atoi (argv[2]);
+
   return CMD_SUCCESS;
 }
 
@@ -6244,9 +6310,12 @@
        "Intra-area routes\n"
        "Distance for intra-area routes\n")
 {
-  ospf_top->distance_external = atoi (argv[0]);
-  ospf_top->distance_inter = atoi (argv[1]);
-  ospf_top->distance_intra = atoi (argv[2]);
+  struct ospf *ospf = vty->index;
+
+  ospf->distance_external = atoi (argv[0]);
+  ospf->distance_inter = atoi (argv[1]);
+  ospf->distance_intra = atoi (argv[2]);
+
   return CMD_SUCCESS;
 }
 
@@ -6258,6 +6327,7 @@
        "IP source prefix\n")
 {
   ospf_distance_set (vty, argv[0], argv[1], NULL);
+
   return CMD_SUCCESS;
 }
 
@@ -6457,13 +6527,15 @@
        "show all the ABR's and ASBR's\n"
        "for this area\n")
 {
-  if (ospf_top == NULL)
+  struct ospf *ospf = ospf_top;
+
+  if (ospf == NULL)
     {
       vty_out (vty, "OSPF is not enabled%s", VTY_NEWLINE);
       return CMD_SUCCESS;
     }
 
-  if (ospf_top->new_table == NULL)
+  if (ospf->new_table == NULL)
     {
       vty_out (vty, "No OSPF routing information exist%s", VTY_NEWLINE);
       return CMD_SUCCESS;
@@ -6473,7 +6545,7 @@
   show_ip_ospf_route_network (vty, ospf_top->new_table);   */
 
   /* Show Router routes. */
-  show_ip_ospf_route_router (vty, ospf_top->new_rtrs);
+  show_ip_ospf_route_router (vty, ospf->new_rtrs);
 
   return CMD_SUCCESS;
 }
@@ -6487,26 +6559,28 @@
        "OSPF information\n"
        "OSPF routing table\n")
 {
-  if (ospf_top == NULL)
+  struct ospf *ospf = ospf_top;
+
+  if (ospf == NULL)
     {
       vty_out (vty, "OSPF is not enabled%s", VTY_NEWLINE);
       return CMD_SUCCESS;
     }
 
-  if (ospf_top->new_table == NULL)
+  if (ospf->new_table == NULL)
     {
       vty_out (vty, "No OSPF routing information exist%s", VTY_NEWLINE);
       return CMD_SUCCESS;
     }
 
   /* Show Network routes. */
-  show_ip_ospf_route_network (vty, ospf_top->new_table);
+  show_ip_ospf_route_network (vty, ospf->new_table);
 
   /* Show Router routes. */
-  show_ip_ospf_route_router (vty, ospf_top->new_rtrs);
+  show_ip_ospf_route_router (vty, ospf->new_rtrs);
 
   /* Show AS External routes. */
-  show_ip_ospf_route_external (vty, ospf_top->old_external_route);
+  show_ip_ospf_route_external (vty, ospf->old_external_route);
 
   return CMD_SUCCESS;
 }
@@ -6735,13 +6809,13 @@
 }
 
 int
-config_write_network_area (struct vty *vty)
+config_write_network_area (struct vty *vty, struct ospf *ospf)
 {
   struct route_node *rn;
   u_char buf[INET_ADDRSTRLEN];
 
   /* `network area' print. */
-  for (rn = route_top (ospf_top->networks); rn; rn = route_next (rn))
+  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
     if (rn->info)
       {
 	struct ospf_network *n = rn->info;
@@ -6765,13 +6839,13 @@
 }
 
 int
-config_write_ospf_area (struct vty *vty)
+config_write_ospf_area (struct vty *vty, struct ospf *ospf)
 {
   listnode node;
   u_char buf[INET_ADDRSTRLEN];
 
   /* Area configuration print. */
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     {
       struct ospf_area *area = getdata (node);
       struct route_node *rn1;
@@ -6857,13 +6931,13 @@
 }
 
 int
-config_write_ospf_nbr_nbma (struct vty *vty)
+config_write_ospf_nbr_nbma (struct vty *vty, struct ospf *ospf)
 {
   struct ospf_nbr_nbma *nbr_nbma;
   struct route_node *rn;
 
   /* Static Neighbor configuration print. */
-  for (rn = route_top (ospf_top->nbr_nbma); rn; rn = route_next (rn))
+  for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
     if ((nbr_nbma = rn->info))
       {
 	vty_out (vty, " neighbor %s", inet_ntoa (nbr_nbma->addr));
@@ -6881,13 +6955,13 @@
 }
 
 int
-config_write_virtual_link (struct vty *vty)
+config_write_virtual_link (struct vty *vty, struct ospf *ospf)
 {
   listnode node;
   u_char buf[INET_ADDRSTRLEN];
 
   /* Virtual-Link print */
-  for (node = listhead (ospf_top->vlinks); node; nextnode (node))
+  for (node = listhead (ospf->vlinks); node; nextnode (node))
     {
       listnode n2;
       struct crypt_key *ck;
@@ -6948,7 +7022,7 @@
 char *distribute_str[] = { "system", "kernel", "connected", "static", "rip",
 			   "ripng", "ospf", "ospf6", "bgp"};
 int
-config_write_ospf_redistribute (struct vty *vty)
+config_write_ospf_redistribute (struct vty *vty, struct ospf *ospf)
 {
   int type;
 
@@ -6957,10 +7031,10 @@
     if (type != zclient->redist_default && zclient->redist[type])
       {
         vty_out (vty, " redistribute %s", distribute_str[type]);
-	if (ospf_top->dmetric[type].value >= 0)
+	if (ospf->dmetric[type].value >= 0)
 	  vty_out (vty, " metric %d", ospf_top->dmetric[type].value);
 	
-        if (ospf_top->dmetric[type].type == EXTERNAL_METRIC_TYPE_1)
+        if (ospf->dmetric[type].type == EXTERNAL_METRIC_TYPE_1)
 	  vty_out (vty, " metric-type 1");
 
 	if (ROUTEMAP_NAME (type))
@@ -6973,40 +7047,40 @@
 }
 
 int
-config_write_ospf_default_metric (struct vty *vty)
+config_write_ospf_default_metric (struct vty *vty, struct ospf *ospf)
 {
-  if (ospf_top->default_metric != -1)
-    vty_out (vty, " default-metric %d%s", ospf_top->default_metric,
+  if (ospf->default_metric != -1)
+    vty_out (vty, " default-metric %d%s", ospf->default_metric,
 	     VTY_NEWLINE);
   return 0;
 }
 
 int
-config_write_ospf_distribute (struct vty *vty)
+config_write_ospf_distribute (struct vty *vty, struct ospf *ospf)
 {
   int type;
 
-  if (ospf_top)
+  if (ospf)
     {
       /* distribute-list print. */
       for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
-	if (ospf_top->dlist[type].name)
+	if (ospf->dlist[type].name)
 	  vty_out (vty, " distribute-list %s out %s%s", 
-		   ospf_top->dlist[type].name,
+		   ospf->dlist[type].name,
 		   distribute_str[type], VTY_NEWLINE);
 
       /* default-information print. */
-      if (ospf_top->default_originate != DEFAULT_ORIGINATE_NONE)
+      if (ospf->default_originate != DEFAULT_ORIGINATE_NONE)
 	{
-	  if (ospf_top->default_originate == DEFAULT_ORIGINATE_ZEBRA)
+	  if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
 	    vty_out (vty, " default-information originate");
 	  else
 	    vty_out (vty, " default-information originate always");
 
-	  if (ospf_top->dmetric[DEFAULT_ROUTE].value >= 0)
+	  if (ospf->dmetric[DEFAULT_ROUTE].value >= 0)
 	    vty_out (vty, " metric %d",
-		     ospf_top->dmetric[DEFAULT_ROUTE].value);
-	  if (ospf_top->dmetric[DEFAULT_ROUTE].type == EXTERNAL_METRIC_TYPE_1)
+		     ospf->dmetric[DEFAULT_ROUTE].value);
+	  if (ospf->dmetric[DEFAULT_ROUTE].type == EXTERNAL_METRIC_TYPE_1)
 	    vty_out (vty, " metric-type 1");
 
 	  if (ROUTEMAP_NAME (DEFAULT_ROUTE))
@@ -7021,31 +7095,31 @@
 }
 
 int
-config_write_ospf_distance (struct vty *vty)
+config_write_ospf_distance (struct vty *vty, struct ospf *ospf)
 {
   struct route_node *rn;
   struct ospf_distance *odistance;
 
-  if (ospf_top->distance_all)
-    vty_out (vty, " distance %d%s", ospf_top->distance_all, VTY_NEWLINE);
+  if (ospf->distance_all)
+    vty_out (vty, " distance %d%s", ospf->distance_all, VTY_NEWLINE);
 
-  if (ospf_top->distance_intra 
-      || ospf_top->distance_inter 
-      || ospf_top->distance_external)
+  if (ospf->distance_intra 
+      || ospf->distance_inter 
+      || ospf->distance_external)
     {
       vty_out (vty, " distance ospf");
 
-      if (ospf_top->distance_intra)
-	vty_out (vty, " intra-area %d", ospf_top->distance_intra);
-      if (ospf_top->distance_inter)
-	vty_out (vty, " inter-area %d", ospf_top->distance_inter);
-      if (ospf_top->distance_external)
-	vty_out (vty, " external %d", ospf_top->distance_external);
+      if (ospf->distance_intra)
+	vty_out (vty, " intra-area %d", ospf->distance_intra);
+      if (ospf->distance_inter)
+	vty_out (vty, " inter-area %d", ospf->distance_inter);
+      if (ospf->distance_external)
+	vty_out (vty, " external %d", ospf->distance_external);
 
       vty_out (vty, "%s", VTY_NEWLINE);
     }
   
-  for (rn = route_top (ospf_top->distance_table); rn; rn = route_next (rn))
+  for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
     if ((odistance = rn->info) != NULL)
       {
 	vty_out (vty, " distance %d %s/%d %s%s", odistance->distance,
@@ -7060,54 +7134,55 @@
 int
 ospf_config_write (struct vty *vty)
 {
+  struct ospf *ospf = ospf_top;
   listnode node;
   int write = 0;
 
-  if (ospf_top != NULL)
+  if (ospf != NULL)
     {
       /* `router ospf' print. */
       vty_out (vty, "router ospf%s", VTY_NEWLINE);
 
       write++;
 
-      if (!ospf_top->networks)
+      if (!ospf->networks)
         return write;
 
       /* Router ID print. */
-      if (ospf_top->router_id_static.s_addr != 0)
+      if (ospf->router_id_static.s_addr != 0)
         vty_out (vty, " ospf router-id %s%s",
-                 inet_ntoa (ospf_top->router_id_static), VTY_NEWLINE);
+                 inet_ntoa (ospf->router_id_static), VTY_NEWLINE);
 
       /* ABR type print. */
-      if (ospf_top->abr_type != OSPF_ABR_STAND)
+      if (ospf->abr_type != OSPF_ABR_STAND)
         vty_out (vty, " ospf abr-type %s%s", 
-                 ospf_abr_type_str[ospf_top->abr_type], VTY_NEWLINE);
+                 ospf_abr_type_str[ospf->abr_type], VTY_NEWLINE);
 
       /* RFC1583 compatibility flag print -- Compatible with CISCO 12.1. */
-      if (CHECK_FLAG (ospf_top->config, OSPF_RFC1583_COMPATIBLE))
+      if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
 	vty_out (vty, " compatible rfc1583%s", VTY_NEWLINE);
 
       /* auto-cost reference-bandwidth configuration.  */
-      if (ospf_top->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH)
+      if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH)
 	vty_out (vty, " auto-cost reference-bandwidth %d%s",
-		 ospf_top->ref_bandwidth / 1000, VTY_NEWLINE);
+		 ospf->ref_bandwidth / 1000, VTY_NEWLINE);
 
       /* SPF timers print. */
-      if (ospf_top->spf_delay != OSPF_SPF_DELAY_DEFAULT ||
-	  ospf_top->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT)
+      if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT ||
+	  ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT)
 	vty_out (vty, " timers spf %d %d%s",
-		 ospf_top->spf_delay, ospf_top->spf_holdtime, VTY_NEWLINE);
+		 ospf->spf_delay, ospf->spf_holdtime, VTY_NEWLINE);
 
       /* SPF refresh parameters print. */
-      if (ospf_top->lsa_refresh_interval != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
+      if (ospf->lsa_refresh_interval != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
 	vty_out (vty, " refresh timer %d%s",
-		 ospf_top->lsa_refresh_interval, VTY_NEWLINE);
+		 ospf->lsa_refresh_interval, VTY_NEWLINE);
 
       /* Redistribute information print. */
-      config_write_ospf_redistribute (vty);
+      config_write_ospf_redistribute (vty, ospf);
 
       /* passive-interface print. */
-      for (node = listhead (ospf_top->iflist); node; nextnode (node))
+      for (node = listhead (ospf->iflist); node; nextnode (node))
         {
           struct interface *ifp = getdata (node);
 
@@ -7118,7 +7193,7 @@
 		     ifp->name, VTY_NEWLINE);
         }
 
-      for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+      for (node = listhead (ospf->oiflist); node; nextnode (node))
         {
           struct ospf_interface *oi = getdata (node);
 
@@ -7130,28 +7205,28 @@
 
       
       /* Network area print. */
-      config_write_network_area (vty);
+      config_write_network_area (vty, ospf);
 
       /* Area config print. */
-      config_write_ospf_area (vty);
+      config_write_ospf_area (vty, ospf);
 
       /* static neighbor print. */
-      config_write_ospf_nbr_nbma (vty);
+      config_write_ospf_nbr_nbma (vty, ospf);
 
       /* Virtual-Link print. */
-      config_write_virtual_link (vty);
+      config_write_virtual_link (vty, ospf);
 
       /* Default metric configuration.  */
-      config_write_ospf_default_metric (vty);
+      config_write_ospf_default_metric (vty, ospf);
 
       /* Distribute-list and default-information print. */
-      config_write_ospf_distribute (vty);
+      config_write_ospf_distribute (vty, ospf);
 
       /* Distance configuration. */
-      config_write_ospf_distance (vty);
+      config_write_ospf_distance (vty, ospf);
 
 #ifdef HAVE_OPAQUE_LSA
-      ospf_opaque_config_write_router (vty, ospf_top);
+      ospf_opaque_config_write_router (vty, ospf);
 #endif /* HAVE_OPAQUE_LSA */
     }
 
@@ -7568,3 +7643,4 @@
   ospf_vty_zebra_init ();
 }
 
+
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index a8e1630..baba11d 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -59,6 +59,7 @@
 ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
 {
   struct interface *ifp;
+  struct ospf *ospf = ospf_top;
 
   ifp = zebra_interface_add_read (zclient->ibuf);
 
@@ -81,7 +82,7 @@
 	IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_LOOPBACK;
     }
 
-  ospf_if_update ();
+  ospf_if_update (ospf);
 
 #ifdef HAVE_SNMP
   ospf_snmp_if_update (ifp);
@@ -245,6 +246,7 @@
 ospf_interface_address_add (int command, struct zclient *zclient,
 			    zebra_size_t length)
 {
+  struct ospf *ospf = ospf_top;
   struct connected *c;
 
   c = zebra_interface_address_add_read (zclient->ibuf);
@@ -252,19 +254,7 @@
   if (c == NULL)
     return 0;
 
-#if 0
-  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
-    {
-      struct prefix *p;
-
-      p = c->address;
-      if (p->family == AF_INET)
-	zlog_info (" connected address %s/%d", 
-		   inet_atop (p->u.prefix4), p->prefixlen);
-    }
-#endif
-
-  ospf_if_update ();
+  ospf_if_update (ospf);
 
 #ifdef HAVE_SNMP
   ospf_snmp_if_update (c->ifp);
@@ -277,6 +267,7 @@
 ospf_interface_address_delete (int command, struct zclient *zclient,
 			       zebra_size_t length)
 {
+  struct ospf *ospf = ospf_top;
   struct connected *c;
   struct interface *ifp;
   struct ospf_interface *oi;
@@ -308,7 +299,7 @@
 
   connected_free (c);
 
-  ospf_if_update();
+  ospf_if_update (ospf);
 
   return 0;
 }
@@ -482,42 +473,43 @@
 int
 ospf_redistribute_set (int type, int mtype, int mvalue)
 {
+  struct ospf *ospf = ospf_top;
   int force = 0;
   
   if (ospf_is_type_redistributed (type))
     {
-      if (mtype != ospf_top->dmetric[type].type)
+      if (mtype != ospf->dmetric[type].type)
 	{
-	  ospf_top->dmetric[type].type = mtype;
+	  ospf->dmetric[type].type = mtype;
 	  force = LSA_REFRESH_FORCE;
 	}
-      if (mvalue != ospf_top->dmetric[type].value)
+      if (mvalue != ospf->dmetric[type].value)
 	{
-	  ospf_top->dmetric[type].value = mvalue;
+	  ospf->dmetric[type].value = mvalue;
 	  force = LSA_REFRESH_FORCE;
 	}
 	  
-      ospf_external_lsa_refresh_type (type, force);
+      ospf_external_lsa_refresh_type (ospf, type, force);
       
       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 	zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
 		   LOOKUP (ospf_redistributed_proto, type),
-		   metric_type (type), metric_value (type));
+		   metric_type (ospf, type), metric_value (ospf, type));
       
       return CMD_SUCCESS;
     }
 
-  ospf_top->dmetric[type].type = mtype;
-  ospf_top->dmetric[type].value = mvalue;
+  ospf->dmetric[type].type = mtype;
+  ospf->dmetric[type].value = mvalue;
 
   zclient_redistribute_set (zclient, type);
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
     zlog_info ("Redistribute[%s]: Start  Type[%d], Metric[%d]",
 	       LOOKUP (ospf_redistributed_proto, type),
-	       metric_type (type), metric_value (type));
+	       metric_type (ospf, type), metric_value (ospf, type));
   
-  ospf_asbr_status_update (++ospf_top->redistribute);
+  ospf_asbr_status_update (ospf, ++ospf->redistribute);
 
   return CMD_SUCCESS;
 }
@@ -525,6 +517,8 @@
 int
 ospf_redistribute_unset (int type)
 {
+  struct ospf *ospf = ospf_top;
+
   if (type == zclient->redist_default)
     return CMD_SUCCESS;
 
@@ -537,13 +531,13 @@
     zlog_info ("Redistribute[%s]: Stop",
 	       LOOKUP (ospf_redistributed_proto, type));
 
-  ospf_top->dmetric[type].type = -1;
-  ospf_top->dmetric[type].value = -1;
+  ospf->dmetric[type].type = -1;
+  ospf->dmetric[type].value = -1;
 
   /* Remove the routes from OSPF table. */
   ospf_redistribute_withdraw (type);
 
-  ospf_asbr_status_update (--ospf_top->redistribute);
+  ospf_asbr_status_update (ospf, --ospf->redistribute);
 
   return CMD_SUCCESS;
 }
@@ -551,48 +545,50 @@
 int
 ospf_redistribute_default_set (int originate, int mtype, int mvalue)
 {
+  struct ospf *ospf = ospf_top;
+
   int force = 0;
   if (ospf_is_type_redistributed (DEFAULT_ROUTE))
     {
-      if (mtype != ospf_top->dmetric[DEFAULT_ROUTE].type)
+      if (mtype != ospf->dmetric[DEFAULT_ROUTE].type)
 	{
-	  ospf_top->dmetric[DEFAULT_ROUTE].type = mtype;
+	  ospf->dmetric[DEFAULT_ROUTE].type = mtype;
 	  force = 1;
 	}
-      if (mvalue != ospf_top->dmetric[DEFAULT_ROUTE].value)
+      if (mvalue != ospf->dmetric[DEFAULT_ROUTE].value)
 	{
 	  force = 1;
-	  ospf_top->dmetric[DEFAULT_ROUTE].value = mvalue;
+	  ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
 	}
       
-      ospf_external_lsa_refresh_default ();
+      ospf_external_lsa_refresh_default (ospf);
       
       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
 	zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
 		   LOOKUP (ospf_redistributed_proto, DEFAULT_ROUTE),
-		   metric_type (DEFAULT_ROUTE),
-		   metric_value (DEFAULT_ROUTE));
+		   metric_type (ospf, DEFAULT_ROUTE),
+		   metric_value (ospf, DEFAULT_ROUTE));
       return CMD_SUCCESS;
     }
 
-  ospf_top->default_originate = originate;
-  ospf_top->dmetric[DEFAULT_ROUTE].type = mtype;
-  ospf_top->dmetric[DEFAULT_ROUTE].value = mvalue;
+  ospf->default_originate = originate;
+  ospf->dmetric[DEFAULT_ROUTE].type = mtype;
+  ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
 
   zclient_redistribute_default_set (zclient);
   
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
     zlog_info ("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
-	       metric_type (DEFAULT_ROUTE), metric_value (DEFAULT_ROUTE));
+	       metric_type (ospf, DEFAULT_ROUTE),
+	       metric_value (ospf, DEFAULT_ROUTE));
 
-
-  if (ospf_top->router_id.s_addr == 0)
-    ospf_top->external_origin |= (1 << DEFAULT_ROUTE);
+  if (ospf->router_id.s_addr == 0)
+    ospf->external_origin |= (1 << DEFAULT_ROUTE);
   else
     thread_add_timer (master, ospf_default_originate_timer,
-		      &ospf_top->default_originate, 1);
+		      &ospf->default_originate, 1);
 
-  ospf_asbr_status_update (++ospf_top->redistribute);
+  ospf_asbr_status_update (ospf, ++ospf->redistribute);
 
   return CMD_SUCCESS;
 }
@@ -600,19 +596,21 @@
 int
 ospf_redistribute_default_unset ()
 {
+  struct ospf *ospf = ospf_top;
+
   if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
     return CMD_SUCCESS;
 
-  ospf_top->default_originate = DEFAULT_ORIGINATE_NONE;
-  ospf_top->dmetric[DEFAULT_ROUTE].type = -1;
-  ospf_top->dmetric[DEFAULT_ROUTE].value = -1;
+  ospf->default_originate = DEFAULT_ORIGINATE_NONE;
+  ospf->dmetric[DEFAULT_ROUTE].type = -1;
+  ospf->dmetric[DEFAULT_ROUTE].value = -1;
 
   zclient_redistribute_default_unset (zclient);
 
   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
     zlog_info ("Redistribute[DEFAULT]: Stop");
   
-  ospf_asbr_status_update (--ospf_top->redistribute);
+  ospf_asbr_status_update (ospf, --ospf->redistribute);
 
   return CMD_SUCCESS;
 }
@@ -620,6 +618,8 @@
 int
 ospf_external_lsa_originate_check (struct external_info *ei)
 {
+  struct ospf *ospf = ospf_top;
+
   /* If prefix is multicast, then do not originate LSA. */
   if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
     {
@@ -630,7 +630,7 @@
 
   /* Take care of default-originate. */
   if (is_prefix_default (&ei->p))
-    if (ospf_top->default_originate == DEFAULT_ORIGINATE_NONE)
+    if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
       {
 	zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA "
 		   "for default");
@@ -642,21 +642,26 @@
 
 /* If connected prefix is OSPF enable interface, then do not announce. */
 int
-ospf_distribute_check_connected (struct external_info *ei)
+ospf_distribute_check_connected (struct ospf *ospf,
+				 struct external_info *ei)
 {
   struct route_node *rn;
 
-  for (rn = route_top (ospf_top->networks); rn; rn = route_next (rn))
+  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
     if (rn->info != NULL)
       if (prefix_match (&rn->p, (struct prefix *)&ei->p))
-	return 0;
+	{
+	  route_unlock_node (rn);
+	  return 0;
+	}
 
   return 1;
 }
 
 /* return 1 if external LSA must be originated, 0 otherwise */
 int
-ospf_redistribute_check (struct external_info *ei, int *changed)
+ospf_redistribute_check (struct ospf *ospf,
+			 struct external_info *ei, int *changed)
 {
   struct route_map_set_values save_values;
   struct prefix_ipv4 *p = &ei->p;
@@ -669,7 +674,8 @@
     return 0;
 
   /* Take care connected route. */
-  if (type == ZEBRA_ROUTE_CONNECT && !ospf_distribute_check_connected (ei))
+  if (type == ZEBRA_ROUTE_CONNECT &&
+      !ospf_distribute_check_connected (ospf, ei))
     return 0;
 
   if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (type))
@@ -746,6 +752,7 @@
   struct in_addr nexthop;
   struct prefix_ipv4 p;
   struct external_info *ei;
+  struct ospf *ospf = ospf_top;
 
   s = zclient->ibuf;
   ifindex = 0;
@@ -782,25 +789,26 @@
     {
       ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
 
-      if (ospf_top->router_id.s_addr == 0)
+      if (ospf->router_id.s_addr == 0)
 	/* Set flags to generate AS-external-LSA originate event
 	   for each redistributed protocols later. */
-	ospf_top->external_origin |= (1 << api.type);
+	ospf->external_origin |= (1 << api.type);
       else
 	{
 	  if (ei)
 	    {
 	      if (is_prefix_default (&p))
-		ospf_external_lsa_refresh_default ();
+		ospf_external_lsa_refresh_default (ospf);
 	      else
 		{
 		  struct ospf_lsa *current;
 
-		  current = ospf_external_info_find_lsa (&ei->p);
+		  current = ospf_external_info_find_lsa (ospf, &ei->p);
 		  if (!current)
-		    ospf_external_lsa_originate (ei);
+		    ospf_external_lsa_originate (ospf, ei);
 		  else if (IS_LSA_MAXAGE (current))
-		    ospf_external_lsa_refresh (current, ei, LSA_REFRESH_FORCE);
+		    ospf_external_lsa_refresh (ospf, current,
+					       ei, LSA_REFRESH_FORCE);
 		  else
 		    zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
 			       inet_ntoa (p.prefix));
@@ -812,9 +820,9 @@
     {
       ospf_external_info_delete (api.type, p);
       if ( !is_prefix_default (&p))
-	ospf_external_lsa_flush (api.type, &p, ifindex, nexthop);
+	ospf_external_lsa_flush (ospf, api.type, &p, ifindex, nexthop);
       else
-	ospf_external_lsa_refresh_default ();
+	ospf_external_lsa_refresh_default (ospf);
     }
 
   return 0;
@@ -822,7 +830,7 @@
 
 
 int
-ospf_distribute_list_out_set (int type, char *name)
+ospf_distribute_list_out_set (struct ospf *ospf, int type, char *name)
 {
   /* Lookup access-list for distribute-list. */
   DISTRIBUTE_LIST (type) = access_list_lookup (AFI_IP, name);
@@ -836,17 +844,17 @@
 
   /* If access-list have been set, schedule update timer. */
   if (DISTRIBUTE_LIST (type))
-    ospf_distribute_list_update (type);
+    ospf_distribute_list_update (ospf, type);
 
   return CMD_SUCCESS;
 }
 
 int
-ospf_distribute_list_out_unset (int type, char *name)
+ospf_distribute_list_out_unset (struct ospf *ospf, int type, char *name)
 {
   /* Schedule update timer. */
   if (DISTRIBUTE_LIST (type))
-    ospf_distribute_list_update (type);
+    ospf_distribute_list_update (ospf, type);
 
   /* Unset distribute-list. */
   DISTRIBUTE_LIST (type) = NULL;
@@ -869,11 +877,12 @@
   struct route_table *rt;
   struct ospf_lsa *lsa;
   u_char type;
+  struct ospf *ospf = ospf_top;
 
   type = (int) THREAD_ARG (thread);
   rt = EXTERNAL_INFO (type);
 
-  ospf_top->t_distribute_update = NULL;
+  ospf->t_distribute_update = NULL;
 
   zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
 
@@ -883,11 +892,11 @@
       if ((ei = rn->info) != NULL)
 	{
 	  if (is_prefix_default (&ei->p))
-	    ospf_external_lsa_refresh_default ();
-	  else if ((lsa = ospf_external_info_find_lsa (&ei->p)))
-	    ospf_external_lsa_refresh (lsa, ei, LSA_REFRESH_IF_CHANGED);
+	    ospf_external_lsa_refresh_default (ospf);
+	  else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
+	    ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
 	  else
-	    ospf_external_lsa_originate (ei);
+	    ospf_external_lsa_originate (ospf, ei);
 	}
   return 0;
 }
@@ -896,49 +905,45 @@
 
 /* Update distribute-list and set timer to apply access-list. */
 void
-ospf_distribute_list_update (int type)
+ospf_distribute_list_update (struct ospf *ospf, int type)
 {
   struct route_table *rt;
   
-  zlog_info ("ospf_distribute_list_update(): start");
-
   /* External info does not exist. */
   if (!(rt = EXTERNAL_INFO (type)))
     return;
 
   /* If exists previously invoked thread, then cancel it. */
-  if (ospf_top->t_distribute_update)
-    OSPF_TIMER_OFF (ospf_top->t_distribute_update);
+  if (ospf->t_distribute_update)
+    OSPF_TIMER_OFF (ospf->t_distribute_update);
 
   /* Set timer. */
-  ospf_top->t_distribute_update =
+  ospf->t_distribute_update =
     thread_add_timer (master, ospf_distribute_list_update_timer,
 		      (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
-
-  zlog_info ("ospf_distribute_list_update(): stop");
 }
 
 /* If access-list is updated, apply some check. */
 void
 ospf_filter_update (struct access_list *access)
 {
+  struct ospf *ospf = ospf_top;
   int type;
   int abr_inv = 0;
   struct ospf_area *area;
   listnode node;
 
   /* If OSPF instatnce does not exist, return right now. */
-  if (!ospf_top)
+  if (ospf == NULL)
     return;
 
-
   /* Update distribute-list, and apply filter. */
   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
     {
       if (ROUTEMAP (type) != NULL)
 	{
 	  /* if route-map is not NULL it may be using this access list */
-	  ospf_distribute_list_update (type);
+	  ospf_distribute_list_update (ospf, type);
 	  continue;
 	}
       
@@ -959,12 +964,12 @@
 	  /* Schedule distribute-list update timer. */
 	  if (DISTRIBUTE_LIST (type) == NULL ||
 	      strcmp (DISTRIBUTE_NAME (type), access->name) == 0)
-	    ospf_distribute_list_update (type);
+	    ospf_distribute_list_update (ospf, type);
 	}
     }
 
   /* Update Area access-list. */
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     if ((area = getdata (node)) != NULL)
       {
 	if (EXPORT_NAME (area))
@@ -982,7 +987,7 @@
 
   /* Schedule ABR tasks -- this will be changed -- takada. */
   if (OSPF_IS_ABR && abr_inv)
-    ospf_schedule_abr_task ();
+    ospf_schedule_abr_task (ospf);
 }
 
 
@@ -1010,6 +1015,7 @@
   u_char distance;
   struct route_node *rn;
   struct ospf_distance *odistance;
+  struct ospf *ospf = ospf_top;
 
   ret = str2prefix_ipv4 (ip_str, &p);
   if (ret == 0)
@@ -1021,7 +1027,7 @@
   distance = atoi (distance_str);
 
   /* Get OSPF distance node. */
-  rn = route_node_get (ospf_top->distance_table, (struct prefix *) &p);
+  rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
   if (rn->info)
     {
       odistance = rn->info;
@@ -1057,6 +1063,7 @@
   u_char distance;
   struct route_node *rn;
   struct ospf_distance *odistance;
+  struct ospf *ospf = ospf_top;
 
   ret = str2prefix_ipv4 (ip_str, &p);
   if (ret == 0)
@@ -1067,7 +1074,7 @@
 
   distance = atoi (distance_str);
 
-  rn = route_node_lookup (ospf_top->distance_table, (struct prefix *)&p);
+  rn = route_node_lookup (ospf->distance_table, (struct prefix *)&p);
   if (! rn)
     {
       vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
@@ -1088,12 +1095,12 @@
 }
 
 void
-ospf_distance_reset ()
+ospf_distance_reset (struct ospf *ospf)
 {
   struct route_node *rn;
   struct ospf_distance *odistance;
 
-  for (rn = route_top (ospf_top->distance_table); rn; rn = route_next (rn))
+  for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
     if ((odistance = rn->info) != NULL)
       {
 	if (odistance->access_list)
@@ -1107,58 +1114,26 @@
 u_char
 ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
 {
-#if 0
-  struct route_node *rn;
-  struct ospf_distance *odistance;
-  struct access_list *alist;
-  struct prefix_ipv4 q;
+  struct ospf *ospf = ospf_top;
 
-  memset (&q, 0, sizeof (struct prefix_ipv4));
-  q.family = AF_INET;
-  /* q.prefix =  */
-  q.prefixlen = IPV4_MAX_BITLEN;
-#endif /* 0 */
-
-  if (! ospf_top)
+  if (ospf == NULL)
     return 0;
 
-#if 0
-  rn = route_node_match (ospf_top->distance_table, (struct prefix *) &q);
-  if (rn)
-    {
-      odistance = rn->info;
-      route_unlock_node (rn);
-
-      if (odistance->access_list)
-	{
-	  alist = access_list_lookup (AFI_IP, odistance->access_list);
-	  if (alist == NULL)
-	    return 0;
-	  if (access_list_apply (alist, (struct prefix *) p) == FILTER_DENY)
-	    return 0;
-
-	  return odistance->distance;
-	}
-      else
-	return odistance->distance;
-    }
-#endif /* 0 */
-
-  if (ospf_top->distance_intra)
+  if (ospf->distance_intra)
     if (or->path_type == OSPF_PATH_INTRA_AREA)
-      return ospf_top->distance_intra;
+      return ospf->distance_intra;
 
-  if (ospf_top->distance_inter)
+  if (ospf->distance_inter)
     if (or->path_type == OSPF_PATH_INTER_AREA)
-      return ospf_top->distance_inter;
+      return ospf->distance_inter;
 
-  if (ospf_top->distance_external)
+  if (ospf->distance_external)
     if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
 	|| or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
-      return ospf_top->distance_external;
+      return ospf->distance_external;
   
-  if (ospf_top->distance_all)
-    return ospf_top->distance_all;
+  if (ospf->distance_all)
+    return ospf->distance_all;
 
   return 0;
 }
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 6e205e6..8d1b786 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -58,8 +58,8 @@
 extern struct zclient *zclient;
 
 
-void ospf_remove_vls_through_area (struct ospf_area *);
-void ospf_network_free (struct ospf_network *);
+void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
+void ospf_network_free (struct ospf *, struct ospf_network *);
 void ospf_area_free (struct ospf_area *);
 void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
 
@@ -93,29 +93,29 @@
 #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
 
 void
-ospf_router_id_update ()
+ospf_router_id_update (struct ospf *ospf)
 {
-  listnode node;
   struct in_addr router_id, router_id_old;
+  listnode node;
 
   if (IS_DEBUG_OSPF_EVENT)
-    zlog_info ("Router-ID[OLD:%s]: Update",inet_ntoa (ospf_top->router_id));
+    zlog_info ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
 
-  router_id_old = ospf_top->router_id;
+  router_id_old = ospf->router_id;
 
-  if (ospf_top->router_id_static.s_addr != 0)
-    router_id = ospf_top->router_id_static;
+  if (ospf->router_id_static.s_addr != 0)
+    router_id = ospf->router_id_static;
   else
-    router_id = ospf_router_id_get (ospf_top->oiflist);
+    router_id = ospf_router_id_get (ospf->oiflist);
 
-  ospf_top->router_id = router_id;
+  ospf->router_id = router_id;
   
   if (IS_DEBUG_OSPF_EVENT)
-    zlog_info ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf_top->router_id));
+    zlog_info ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
 
   if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
     {
-      for (node = listhead (ospf_top->oiflist); node; nextnode (node))
+      for (node = listhead (ospf->oiflist); node; nextnode (node))
         {
 	  struct ospf_interface *oi = getdata (node);
 
@@ -124,23 +124,23 @@
         }
 
       /* If AS-external-LSA is queued, then flush those LSAs. */
-      if (router_id_old.s_addr == 0 && ospf_top->external_origin)
+      if (router_id_old.s_addr == 0 && ospf->external_origin)
 	{
 	  int type;
 	  /* Originate each redistributed external route. */
 	  for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
-	    if (ospf_top->external_origin & (1 << type))
+	    if (ospf->external_origin & (1 << type))
 	      thread_add_event (master, ospf_external_lsa_originate_timer,
-				NULL, type);
+				ospf, type);
 	  /* Originate Deafult. */
-	  if (ospf_top->external_origin & (1 << ZEBRA_ROUTE_MAX))
+	  if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
 	    thread_add_event (master, ospf_default_originate_timer,
-			      &ospf_top->default_originate, 0);
+			      &ospf->default_originate, 0);
 
-	  ospf_top->external_origin = 0;
+	  ospf->external_origin = 0;
 	}
 
-      OSPF_TIMER_ON (ospf_top->t_router_lsa_update,
+      OSPF_TIMER_ON (ospf->t_router_lsa_update,
 		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
     }
 }
@@ -148,11 +148,13 @@
 int
 ospf_router_id_update_timer (struct thread *thread)
 {
+  struct ospf *ospf = ospf_top;
+
   if (IS_DEBUG_OSPF_EVENT)
     zlog_info ("Router-ID: Update timer fired!");
 
-  ospf_top->t_router_id_update = NULL;
-  ospf_router_id_update ();
+  ospf->t_router_id_update = NULL;
+  ospf_router_id_update (ospf);
 
   return 0;
 }
@@ -213,7 +215,7 @@
   new->maxage_lsa = list_new ();
   new->t_maxage_walker =
     thread_add_timer (master, ospf_lsa_maxage_walker,
-                      NULL, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
+                      new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
 
   /* Distance table init. */
   new->distance_table = route_table_init ();
@@ -235,19 +237,23 @@
 struct ospf *
 ospf_get ()
 {
-  if (ospf_top != NULL)
-    return ospf_top;
+  struct ospf *ospf = ospf_top;
 
-  ospf_top = ospf_new ();
+  if (ospf != NULL)
+    return ospf;
 
-  if (ospf_top->router_id_static.s_addr == 0)
-    ospf_router_id_update ();
+  ospf = ospf_new ();
+
+  if (ospf->router_id_static.s_addr == 0)
+    ospf_router_id_update (ospf);
 
 #ifdef HAVE_OPAQUE_LSA
-  ospf_opaque_type11_lsa_init (ospf_top);
+  ospf_opaque_type11_lsa_init (ospf);
 #endif /* HAVE_OPAQUE_LSA */
 
-  return ospf_top;
+  ospf_top = ospf;
+
+  return ospf;
 }
 
 void
@@ -255,6 +261,7 @@
 {
   struct route_node *rn;
   struct ospf_nbr_nbma *nbr_nbma;
+  struct ospf_lsa *lsa;
   listnode node;
   int i;
 
@@ -271,7 +278,7 @@
       struct ospf_area *area = getdata (node);
       nextnode (node);
       
-      ospf_remove_vls_through_area (area);
+      ospf_remove_vls_through_area (ospf, area);
     }
   
   for (node = listhead (ospf->vlinks); node; )
@@ -279,7 +286,7 @@
       struct ospf_vl_data *vl_data = node->data;
       nextnode (node);
       
-      ospf_vl_delete (vl_data);
+      ospf_vl_delete (ospf, vl_data);
     }
   
   list_delete (ospf->vlinks);
@@ -324,7 +331,7 @@
 
       if ((network = rn->info) != NULL)
 	{
-	  ospf_network_free (network);
+	  ospf_network_free (ospf, network);
 	  rn->info = NULL;
 	  route_unlock_node (rn);
 	}
@@ -356,11 +363,12 @@
   close (ospf->fd);
    
 #ifdef HAVE_OPAQUE_LSA
-  foreach_lsa (OPAQUE_AS_LSDB (ospf), ospf_top->lsdb, 0,
-	       ospf_lsa_discard_callback);
+  LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
+    ospf_discard_from_db (ospf, ospf->lsdb, lsa);
 #endif /* HAVE_OPAQUE_LSA */
-  foreach_lsa (EXTERNAL_LSDB (ospf), ospf->lsdb, 0,
-	       ospf_lsa_discard_callback);
+  LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
+    ospf_discard_from_db (ospf, ospf->lsdb, lsa);
+
   ospf_lsdb_delete_all (ospf->lsdb);
   ospf_lsdb_free (ospf->lsdb);
 
@@ -409,7 +417,7 @@
 	  route_unlock_node (rn);
 	}
 
-  ospf_distance_reset ();
+  ospf_distance_reset (ospf);
   route_table_finish (ospf->distance_table);
 
   XFREE (MTYPE_OSPF_TOP, ospf);
@@ -420,14 +428,14 @@
 
 /* allocate new OSPF Area object */
 struct ospf_area *
-ospf_area_new (struct in_addr area_id)
+ospf_area_new (struct ospf *ospf, struct in_addr area_id)
 {
   struct ospf_area *new;
 
   /* Allocate new config_network. */
   new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
 
-  new->top = ospf_top;
+  new->ospf = ospf;
 
   new->area_id = area_id;
 
@@ -449,7 +457,7 @@
   new->ranges = route_table_init ();
 
   if (area_id.s_addr == OSPF_AREA_BACKBONE)
-    ospf_top->backbone = new;
+    ospf->backbone = new;
 
   return new;
 }
@@ -457,22 +465,28 @@
 void
 ospf_area_free (struct ospf_area *area)
 {
+  struct route_node *rn;
+  struct ospf_lsa *lsa;
+
   /* Free LSDBs. */
-  foreach_lsa (ROUTER_LSDB (area), area->lsdb, 0, ospf_lsa_discard_callback);
-  foreach_lsa (NETWORK_LSDB (area), area->lsdb, 0, ospf_lsa_discard_callback);
-  foreach_lsa (SUMMARY_LSDB (area), area->lsdb, 0, ospf_lsa_discard_callback);
-  foreach_lsa (ASBR_SUMMARY_LSDB (area), area->lsdb, 0,
-	       ospf_lsa_discard_callback);
+  LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
+    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
+  LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
+    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
+  LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
+    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
+  LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
+    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
 
 #ifdef HAVE_NSSA
-  foreach_lsa (NSSA_LSDB (area), area->lsdb, 0, ospf_lsa_discard_callback);
+  LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
+    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
 #endif /* HAVE_NSSA */
 #ifdef HAVE_OPAQUE_LSA
-  foreach_lsa (OPAQUE_AREA_LSDB (area), area->lsdb, 0,
-               ospf_lsa_discard_callback);
-  foreach_lsa (OPAQUE_LINK_LSDB (area), area->lsdb, 0,
-               ospf_lsa_discard_callback);
-  ospf_opaque_type10_lsa_term (area);
+  LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
+    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
+  LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
+    ospf_discard_from_db (area->ospf, area->lsdb, lsa);
 #endif /* HAVE_OPAQUE_LSA */
 
   ospf_lsdb_delete_all (area->lsdb);
@@ -493,17 +507,17 @@
   OSPF_TIMER_OFF (area->t_router_lsa_self);
 
   if (OSPF_IS_AREA_BACKBONE (area))
-    ospf_top->backbone = NULL;
+    area->ospf->backbone = NULL;
 
   XFREE (MTYPE_OSPF_AREA, area);
 }
 
 void
-ospf_area_check_free (struct in_addr area_id)
+ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
 {
   struct ospf_area *area;
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area &&
       listcount (area->oiflist) == 0 &&
       area->ranges->top == NULL &&
@@ -515,35 +529,35 @@
       IMPORT_NAME (area) == NULL &&
       area->auth_type == OSPF_AUTH_NULL)
     {
-      listnode_delete (ospf_top->areas, area);
+      listnode_delete (ospf->areas, area);
       ospf_area_free (area);
     }
 }
 
 struct ospf_area *
-ospf_area_get (struct in_addr area_id, int format)
+ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
 {
   struct ospf_area *area;
   
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (!area)
     {
-      area = ospf_area_new (area_id);
+      area = ospf_area_new (ospf, area_id);
       area->format = format;
-      listnode_add_sort (ospf_top->areas, area);
-      ospf_check_abr_status ();  
+      listnode_add_sort (ospf->areas, area);
+      ospf_check_abr_status (ospf);  
     }
 
   return area;
 }
 
 struct ospf_area *
-ospf_area_lookup_by_area_id (struct in_addr area_id)
+ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
 {
   struct ospf_area *area;
   listnode node;
 
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     {
       area = getdata (node);
 
@@ -581,10 +595,10 @@
 }
 
 void
-ospf_network_free (struct ospf_network *network)
+ospf_network_free (struct ospf *ospf, struct ospf_network *network)
 {
-  ospf_area_check_free (network->area_id);
-  ospf_schedule_abr_task ();
+  ospf_area_check_free (ospf, network->area_id);
+  ospf_schedule_abr_task (ospf);
   XFREE (MTYPE_OSPF_NETWORK, network);
 }
 
@@ -607,7 +621,7 @@
     }
 
   rn->info = network = ospf_network_new (area_id, ret);
-  area = ospf_area_get (area_id, ret);
+  area = ospf_area_get (ospf, area_id, ret);
 
   /* Run network config now. */
   ospf_network_run (ospf, (struct prefix *)p, area);
@@ -618,12 +632,12 @@
       for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
 	   rn; rn = route_next (rn))
 	if ((ei = rn->info) != NULL)
-	  if (ospf_external_info_find_lsa (&ei->p))
-	    if (!ospf_distribute_check_connected (ei))
-	      ospf_external_lsa_flush (ei->type, &ei->p,
+	  if (ospf_external_info_find_lsa (ospf, &ei->p))
+	    if (!ospf_distribute_check_connected (ospf, ei))
+	      ospf_external_lsa_flush (ospf, ei->type, &ei->p,
 				       ei->ifindex, ei->nexthop);
 
-  ospf_area_check_free (area_id);
+  ospf_area_check_free (ospf, area_id);
 
   return 1;
 }
@@ -644,11 +658,11 @@
   if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
     return 0;
 
-  ospf_network_free (rn->info);
+  ospf_network_free (ospf, rn->info);
   rn->info = NULL;
   route_unlock_node (rn);
 
-  ospf_if_update ();
+  ospf_if_update (ospf);
   
   /* Update connected redistribute. */
   if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
@@ -656,9 +670,9 @@
       for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
 	   rn; rn = route_next (rn))
 	if ((ei = rn->info) != NULL)
-	  if (!ospf_external_info_find_lsa (&ei->p))
-	    if (ospf_distribute_check_connected (ei))
-	      ospf_external_lsa_originate (ei);
+	  if (!ospf_external_info_find_lsa (ospf, &ei->p))
+	    if (ospf_distribute_check_connected (ospf, ei))
+	      ospf_external_lsa_originate (ospf, ei);
 
   return 1;
 }
@@ -721,13 +735,13 @@
 	    addr = co->address;
 
 	  if (p->family == co->address->family 
-	      && ! ospf_if_is_configured (&(addr->u.prefix4))
+	      && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
 	      && ospf_network_match_iface(co,p))
 	    {
 		struct ospf_interface *oi;
 		assert(co);
 		
-		oi = ospf_if_new (ifp, co->address);
+		oi = ospf_if_new (ospf, ifp, co->address);
 		oi->connected = co;
 		
 		oi->nbr_self->address = *oi->address;
@@ -746,11 +760,11 @@
 		ospf_nbr_add_self (oi);
 
 		/* Make sure pseudo neighbor's router_id. */
-		oi->nbr_self->router_id = ospf_top->router_id;
+		oi->nbr_self->router_id = ospf->router_id;
 		oi->nbr_self->src = oi->address->u.prefix4;
 		
 		/* Relate ospf interface to ospf instance. */
-		oi->ospf = ospf_top;
+		oi->ospf = ospf;
 
 		/* update network type as interface flag */
 		/* If network type is specified previously,
@@ -814,7 +828,7 @@
 }
 
 void
-ospf_if_update ()
+ospf_if_update (struct ospf *ospf)
 {
   struct route_node *rn;
   listnode node;
@@ -822,19 +836,19 @@
   struct ospf_network *network;
   struct ospf_area *area;
 
-  if (ospf_top != NULL)
+  if (ospf != NULL)
     {
       /* Update Router ID scheduled. */
-      if (ospf_top->router_id_static.s_addr == 0)
-        if (ospf_top->t_router_id_update == NULL)
+      if (ospf->router_id_static.s_addr == 0)
+        if (ospf->t_router_id_update == NULL)
           {
-            ospf_top->t_router_id_update =
+            ospf->t_router_id_update =
               thread_add_timer (master, ospf_router_id_update_timer, NULL,
                                 OSPF_ROUTER_ID_UPDATE_DELAY);
           }
 
       /* Find interfaces that not configured already.  */
-      for (node = listhead (ospf_top->oiflist); node; node = next)
+      for (node = listhead (ospf->oiflist); node; node = next)
 	{
 	  int found = 0;
 	  struct ospf_interface *oi = getdata (node);
@@ -845,7 +859,7 @@
 	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
 	    continue;
 	  
-	  for (rn = route_top (ospf_top->networks); rn; rn = route_next (rn))
+	  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
 	    {
 	      if (rn->info == NULL)
 		continue;
@@ -863,28 +877,28 @@
 	}
 	
       /* Run each interface. */
-      for (rn = route_top (ospf_top->networks); rn; rn = route_next (rn))
+      for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
 	if (rn->info != NULL)
 	  {
 	    network = (struct ospf_network *) rn->info;
-	    area = ospf_area_get (network->area_id, network->format);
-	    ospf_network_run (ospf_top, &rn->p, area);
+	    area = ospf_area_get (ospf, network->area_id, network->format);
+	    ospf_network_run (ospf, &rn->p, area);
 	  }
     }
 }
 
 void
-ospf_remove_vls_through_area (struct ospf_area *area)
+ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
 {
   listnode node, next;
   struct ospf_vl_data *vl_data;
 
-  for (node = listhead (ospf_top->vlinks); node; node = next)
+  for (node = listhead (ospf->vlinks); node; node = next)
     {
       next = node->next;
       if ((vl_data = getdata (node)) != NULL)
 	if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
-	  ospf_vl_delete (vl_data);
+	  ospf_vl_delete (ospf, vl_data);
     }
 }
 
@@ -956,31 +970,31 @@
     }
 
   ospf_router_lsa_timer_add (area);
-  ospf_schedule_abr_task ();
+  ospf_schedule_abr_task (area->ospf);
 }
 
 int
-ospf_area_shortcut_set (struct ospf_area *area, int mode)
+ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
 {
   if (area->shortcut_configured == mode)
     return 0;
 
   area->shortcut_configured = mode;
   ospf_router_lsa_timer_add (area);
-  ospf_schedule_abr_task ();
+  ospf_schedule_abr_task (ospf);
 
-  ospf_area_check_free (area->area_id);
+  ospf_area_check_free (ospf, area->area_id);
 
   return 1;
 }
 
 int
-ospf_area_shortcut_unset (struct ospf_area *area)
+ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
 {
   area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
   ospf_router_lsa_timer_add (area);
-  ospf_area_check_free (area->area_id);
-  ospf_schedule_abr_task ();
+  ospf_area_check_free (ospf, area->area_id);
+  ospf_schedule_abr_task (ospf);
 
   return 1;
 }
@@ -1008,7 +1022,7 @@
   struct ospf_area *area;
   int format = OSPF_AREA_ID_FORMAT_DECIMAL;
 
-  area = ospf_area_get (area_id, format);
+  area = ospf_area_get (ospf, area_id, format);
   if (ospf_area_vlink_count (ospf, area))
     return 0;
 
@@ -1023,14 +1037,14 @@
 {
   struct ospf_area *area;
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return 1;
 
   if (area->external_routing == OSPF_AREA_STUB)
     ospf_area_type_set (area, OSPF_AREA_DEFAULT);
 
-  ospf_area_check_free (area_id);
+  ospf_area_check_free (ospf, area_id);
 
   return 1;
 }
@@ -1041,7 +1055,7 @@
   struct ospf_area *area;
   int format = OSPF_AREA_ID_FORMAT_DECIMAL;
 
-  area = ospf_area_get (area_id, format);
+  area = ospf_area_get (ospf, area_id, format);
   area->no_summary = 1;
 
   return 1;
@@ -1052,12 +1066,12 @@
 {
   struct ospf_area *area;
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return 0;
 
   area->no_summary = 0;
-  ospf_area_check_free (area_id);
+  ospf_area_check_free (ospf, area_id);
 
   return 1;
 }
@@ -1068,7 +1082,7 @@
   struct ospf_area *area;
   int format = OSPF_AREA_ID_FORMAT_DECIMAL;
 
-  area = ospf_area_get (area_id, format);
+  area = ospf_area_get (ospf, area_id, format);
   if (ospf_area_vlink_count (ospf, area))
     return 0;
 
@@ -1086,7 +1100,7 @@
 {
   struct ospf_area *area;
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return 0;
 
@@ -1096,7 +1110,7 @@
       ospf_area_type_set (area, OSPF_AREA_DEFAULT);
     }
 
-  ospf_area_check_free (area_id);
+  ospf_area_check_free (ospf, area_id);
 
   return 1;
 }
@@ -1107,7 +1121,7 @@
 {
   struct ospf_area *area;
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return 0;
 
@@ -1122,19 +1136,20 @@
 {
   struct ospf_area *area;
 
-  area = ospf_area_lookup_by_area_id (area_id);
+  area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return 0;
 
   area->NSSATranslator = OSPF_NSSA_ROLE_CANDIDATE;
 
-  ospf_area_check_free (area_id);
+  ospf_area_check_free (ospf, area_id);
 
   return 1;
 }
 
 int
-ospf_area_export_list_set (struct ospf_area *area, char *list_name)
+ospf_area_export_list_set (struct ospf *ospf,
+			   struct ospf_area *area, char *list_name)
 {
   struct access_list *list;
   list = access_list_lookup (AFI_IP, list_name);
@@ -1145,13 +1160,13 @@
     free (EXPORT_NAME (area));
 
   EXPORT_NAME (area) = strdup (list_name);
-  ospf_schedule_abr_task ();
+  ospf_schedule_abr_task (ospf);
 
   return 1;
 }
 
 int
-ospf_area_export_list_unset (struct ospf_area * area)
+ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
 {
 
   EXPORT_LIST (area) = 0;
@@ -1161,15 +1176,16 @@
 
   EXPORT_NAME (area) = NULL;
 
-  ospf_area_check_free (area->area_id);
+  ospf_area_check_free (ospf, area->area_id);
   
-  ospf_schedule_abr_task ();
+  ospf_schedule_abr_task (ospf);
 
   return 1;
 }
 
 int
-ospf_area_import_list_set (struct ospf_area *area, char *name)
+ospf_area_import_list_set (struct ospf *ospf,
+			   struct ospf_area *area, char *name)
 {
   struct access_list *list;
   list = access_list_lookup (AFI_IP, name);
@@ -1180,13 +1196,13 @@
     free (IMPORT_NAME (area));
 
   IMPORT_NAME (area) = strdup (name);
-  ospf_schedule_abr_task ();
+  ospf_schedule_abr_task (ospf);
 
   return 1;
 }
 
 int
-ospf_area_import_list_unset (struct ospf_area * area)
+ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
 {
   IMPORT_LIST (area) = 0;
 
@@ -1194,9 +1210,9 @@
     free (IMPORT_NAME (area));
 
   IMPORT_NAME (area) = NULL;
-  ospf_area_check_free (area->area_id);
+  ospf_area_check_free (ospf, area->area_id);
 
-  ospf_schedule_abr_task ();
+  ospf_schedule_abr_task (ospf);
 
   return 1;
 }
@@ -1369,7 +1385,7 @@
 }
 
 void
-ospf_nbr_nbma_if_update (struct ospf_interface *oi)
+ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
 {
   struct ospf_nbr_nbma *nbr_nbma;
   struct route_node *rn;
@@ -1378,7 +1394,7 @@
   if (oi->type != OSPF_IFTYPE_NBMA)
     return;
 
-  for (rn = route_top (ospf_top->nbr_nbma); rn; rn = route_next (rn))
+  for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
     if ((nbr_nbma = rn->info))
       if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
 	{
@@ -1411,18 +1427,18 @@
 }
 
 struct ospf_nbr_nbma *
-ospf_nbr_nbma_lookup_next (struct in_addr *addr, int first)
+ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
 {
 #if 0
   struct ospf_nbr_nbma *nbr_nbma;
   listnode node;
 #endif
 
-  if (! ospf_top)
+  if (ospf == NULL)
     return NULL;
 
 #if 0
-  for (node = listhead (ospf_top->nbr_nbma); node; nextnode (node))
+  for (node = listhead (ospf->nbr_nbma); node; nextnode (node))
     {
       nbr_nbma = getdata (node);
 
@@ -1567,16 +1583,17 @@
 void
 ospf_prefix_list_update (struct prefix_list *plist)
 {
+  struct ospf *ospf = ospf_top;
   struct ospf_area *area;
   listnode node;
   int abr_inv = 0;
 
   /* If OSPF instatnce does not exist, return right now. */
-  if (!ospf_top)
+  if (ospf == NULL)
     return;
 
   /* Update Area prefix-list. */
-  for (node = listhead (ospf_top->areas); node; nextnode (node))
+  for (node = listhead (ospf->areas); node; nextnode (node))
     {
       area = getdata (node);
 
@@ -1601,7 +1618,7 @@
 
   /* Schedule ABR tasks. */
   if (OSPF_IS_ABR && abr_inv)
-    ospf_schedule_abr_task ();
+    ospf_schedule_abr_task (ospf);
 }
 
 void
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index a46a793..be80621 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -32,6 +32,11 @@
 #define IPPROTO_OSPFIGP         89
 #endif /* IPPROTO_OSPFIGP */
 
+/* IP precedence. */
+#ifndef IPTOS_PREC_INTERNETCONTROL
+#define IPTOS_PREC_INTERNETCONTROL	0xC0
+#endif /* IPTOS_PREC_INTERNETCONTROL */
+
 /* VTY port number. */
 #define OSPF_VTY_PORT          2604
 #define OSPF_VTYSH_PATH        "/tmp/.ospfd"
@@ -288,7 +293,7 @@
 struct ospf_area
 {
   /* OSPF instance. */
-  struct ospf *top;
+  struct ospf *ospf;
 
   /* Zebra interface list belonging to the area. */
   list oiflist;
@@ -456,7 +461,7 @@
 #define OSPF_TIMER_ON(T,F,V)                                                  \
     do {                                                                      \
       if (!(T))                                                               \
-	(T) = thread_add_timer (master, (F), NULL, (V));                      \
+	(T) = thread_add_timer (master, (F), ospf, (V));                      \
     } while (0)
 
 #define OSPF_AREA_TIMER_ON(T,F,V)                                             \
@@ -482,12 +487,6 @@
         }                                                                     \
     } while (0)
 
-#define OSPF_SCHEDULE_MAXAGE(T, F)                                            \
-    do {                                                                      \
-      if (!(T))                                                               \
-        (T) = thread_add_timer (master, (F), 0, 2);                           \
-    } while (0)
-
 /* Messages */
 extern struct message ospf_ism_state_msg[];
 extern struct message ospf_nsm_state_msg[];
@@ -521,12 +520,12 @@
 int ospf_area_nssa_set (struct ospf *, struct in_addr);
 int ospf_area_nssa_unset (struct ospf *, struct in_addr);
 int ospf_area_nssa_translator_role_set (struct ospf *, struct in_addr, int);
-int ospf_area_export_list_set (struct ospf_area *, char *);
-int ospf_area_export_list_unset (struct ospf_area *);
-int ospf_area_import_list_set (struct ospf_area *, char *);
-int ospf_area_import_list_unset (struct ospf_area *);
-int ospf_area_shortcut_set (struct ospf_area *, int);
-int ospf_area_shortcut_unset (struct ospf_area *);
+int ospf_area_export_list_set (struct ospf *, struct ospf_area *, char *);
+int ospf_area_export_list_unset (struct ospf *, struct ospf_area *);
+int ospf_area_import_list_set (struct ospf *, struct ospf_area *, char *);
+int ospf_area_import_list_unset (struct ospf *, struct ospf_area *);
+int ospf_area_shortcut_set (struct ospf *, struct ospf_area *, int);
+int ospf_area_shortcut_unset (struct ospf *, struct ospf_area *);
 int ospf_timers_spf_set (struct ospf *, u_int32_t, u_int32_t);
 int ospf_timers_spf_unset (struct ospf *);
 int ospf_timers_refresh_set (struct ospf *, int);
@@ -539,18 +538,18 @@
 int ospf_nbr_nbma_poll_interval_unset (struct ospf *, struct in_addr);
 void ospf_prefix_list_update (struct prefix_list *);
 void ospf_init ();
-void ospf_if_update ();
+void ospf_if_update (struct ospf *);
 void ospf_ls_upd_queue_empty (struct ospf_interface *);
 void ospf_terminate ();
-void ospf_nbr_nbma_if_update (struct ospf_interface *);
+void ospf_nbr_nbma_if_update (struct ospf *, struct ospf_interface *);
 struct ospf_nbr_nbma *ospf_nbr_nbma_lookup (struct ospf *, struct in_addr);
-struct ospf_nbr_nbma *ospf_nbr_nbma_lookup_next (struct in_addr *, int);
+struct ospf_nbr_nbma *ospf_nbr_nbma_lookup_next (struct ospf *,
+						 struct in_addr *, int);
 int ospf_oi_count (struct interface *);
 
-struct ospf_area *ospf_area_new (struct in_addr);
-struct ospf_area *ospf_area_get (struct in_addr, int);
-void ospf_area_check_free (struct in_addr);
-struct ospf_area *ospf_area_lookup_by_area_id (struct in_addr);
+struct ospf_area *ospf_area_get (struct ospf *, struct in_addr, int);
+void ospf_area_check_free (struct ospf *, struct in_addr);
+struct ospf_area *ospf_area_lookup_by_area_id (struct ospf *, struct in_addr);
 void ospf_area_add_if (struct ospf_area *, struct ospf_interface *);
 void ospf_area_del_if (struct ospf_area *, struct ospf_interface *);