Merge branch 'restricted-mode'
diff --git a/HACKING b/HACKING
index ec9aa7c..d0fd4b3 100644
--- a/HACKING
+++ b/HACKING
@@ -1,5 +1,21 @@
 -*- mode: text; -*-
-$Id$
+$QuaggaId: Format:%an, %ai, %h$ $
+
+Contents:
+
+* GUIDELINES FOR HACKING ON QUAGGA
+* COMPILE-TIME CONDITIONAL CODE
+* COMMIT MESSAGE
+* HACKING THE BUILD SYSTEM
+* RELEASE PROCEDURE
+* SHARED LIBRARY VERSIONING
+* RELEASE PROCEDURE
+* TOOL VERSIONS
+* SHARED LIBRARY VERSIONING
+* PATCH SUBMISSION
+* PATCH APPLICATION
+* STABLE PLATFORMS AND DAEMONS
+* IMPORT OR UPDATE VENDOR SPECIFIC ROUTING PROTOCOLS
 
 GUIDELINES FOR HACKING ON QUAGGA
 
@@ -31,10 +47,17 @@
 should in many cases upgrade the comments when necessary for a
 reviewer to conclude that the change has no unintended consequences.
 
-Each file in CVS should have the RCS keyword Id, somewhere very near
-the top, commented out appropriately for the file type.  Just add
-<dollar>Id:<dollar>, replacing <dollar> with $.  See line 2 of HACKING
-for an example; on checkout :$ is expanded to include the value.
+Each file in the Git repository should have a git format-placeholder (like
+an RCS Id keyword), somewhere very near the top, commented out appropriately
+for the file type. The placeholder used for Quagga (replacing <dollar> with
+$) is:
+
+	$QuaggaId: <dollar>Format:%an, %ai, %h<dollar> $
+
+See line 2 of HACKING for an example;
+
+This placeholder string will be expanded out by the 'git archive' commands,
+wihch is used to generate the tar archives for snapshots and releases.
 
 Please document fully the proper use of a new function in the header file
 in which it is declared.  And please consult existing headers for
@@ -98,44 +121,34 @@
 Note that the former approach requires ensuring that SOME_SYMBOL will be
 defined (watch your AC_DEFINEs).
 
-CHANGELOG
+COMMIT MESSAGES
 
-Add a ChangeLog entry whenever changing code, except for minor fixes
-to a commit (with a ChangeLog entry) within the last few days.
+The commit message should provide:
 
-Most directories have a ChangeLog file; changes to code in that
-directory should go in the per-directory ChangeLog.  Global or
-structural changes should also be mentioned in the top-level
-ChangeLog.
+* A suitable one-line summary as the very first line of the message, in the
+  form:
 
-Certain directories do not contain project code, but contain project
-meta-data, eg packaging information, changes to files in these
-directory may not require the global ChangeLog to be updated (at the
-discretion of the maintainer who usually maintains that meta-data).
-Also, CVS meta-data such as cvsignore files do not require ChangeLog
-updates, just a sane commit message.
+  [topic] high-level, one line summary
 
-The ChangeLog should provide:
+  Where topic may be name of a subdirectory, and/or daemon. 
 
-* The date, in YYYY-MM-DD format
-* The author's name and email.
-* a short description of each change made
+* An optional introduction, discussing the general intent of the change.
+* a short description of each change made, preferably:
   * file by file
-    * function by function (use of "ditto" is allowed)
+    * function by function (use of "ditto", or globs is allowed)
 
-(detailed discussion of non-obvious reasoning behind and/or
-implications of a change should be made in comments in the code
-concerned). The changelog optionally may have a (general) description,
-to provide a short description of the general intent of the patch. The
-reason for such itemised ChangeLogs is to encourage the author to
-self-review every line of the patch, as well as provide reviewers an
-index of which changes are intended, along with a short description for
-each. E.g.:
+to provide a short description of the general intent of the patch. 
 
-2012-05-29 Joe Bar <joe@example.com>
+The reason for such itemised commit messages is to encourage the author to
+self-review every line of the patch, as well as provide reviewers an index
+of which changes are intended, along with a short description for each.
+An example (where the general discussion is obviously somewhat redundant,
+given the one-line summary):
+
+[zebra] Enhance frob FSM to detect loss of frob
 
 	* (general) Add a new DOWN state to the frob state machine
-	  to allow the barinator to detect loss of frob.
+	  to allow the barinator to detect loss of frob. 
 	* frob.h: (struct frob) Add DOWN state flag.
 	* frob.c: (frob_change) set/clear DOWN appropriately on state
 	  change.
@@ -152,26 +165,35 @@
 	- out-of-tree builds 
 
 The quagga.net site relies on make dist to work to generate snapshots. It
-must work. Commong problems are to forget to have some additional file
+must work. Common problems are to forget to have some additional file
 included in the dist, or to have a make rule refer to a source file without
 using the srcdir variable.
 
 RELEASE PROCEDURE
 
-  Tag the repository with release tag (follow existing conventions).
+* Tag the apppropriate commit with a release tag (follow existing
+  conventions).
   [This enables recreating the release, and is just good CM practice.]
 
-  Check out the tag, and do a test build.
+* Create a fresh tar archive of the quagga.net repository, and do a test
+  build:
 
-  In an empty directory, do a fresh checkout with -r <release-tag>
-  [This makes the dates in the tarball be the modified dates in CVS.]
+    git-clone git:///code.quagga.net/quagga.git quagga
+    git-archive --remote=git://code.quagga.net/quagga.git \
+        --prefix=quagga-release/ master | tar -xf -
+    cd quagga-release
 
-  ./configure
-  make dist
+    ./update-autotools
+    ./configure
+    make
+    make dist
 
-If any errors occur, move tags as needed and start over from the fresh
-checkouts.  Do not append to tarballs, as this has produced
-non-standards-conforming tarballs in the past.
+The tarball which 'make dist' creates is the tarball to be released! The
+git-archive step ensures you're working with code corresponding to that in
+the official repository, and also carries out keyword expansion. If any
+errors occur, move tags as needed and start over from the fresh checkouts. 
+Do not append to tarballs, as this has produced non-standards-conforming
+tarballs in the past.
 
 [TODO: collation of a list of deprecated commands. Possibly can be scripted
 to extract from vtysh/vtysh_cmd.c]
@@ -209,13 +231,21 @@
 
 PATCH SUBMISSION
 
-* Send a clean diff against the head of CVS in unified diff format, eg by:
-  cvs <cvs opts> diff -upwb ....
+* Send a clean diff against the 'master' branch of the quagga.git
+  repository, in unified diff format, preferably with the '-p' argument to 
+  show C function affected by any chunk, and with the -w and -b arguments to
+  minimise changes. E.g: 
 
-* Include ChangeLog and NEWS entries as appropriate before the patch
-  (or in it if you are 100% up to date). A good ChangeLog makes it easier to
-  review a patch, hence failure to include a good ChangeLog is prejudicial
-  to proper review of the patch, and hence the possibility of inclusion.
+    git diff -u -p -w -b mybranch..remotes/quagga.net/master
+
+  Or by using git-format-patch.
+
+*  Not doing so is a definite hindrance to patch application.
+
+* Include NEWS entries as appropriate. 
+
+* Please, please include an appropriate commit message with any emailed
+  patches. Doing so makes it easier to review a patch, and apply it.
 
 * Include only one semantic change or group of changes per patch.
 
@@ -233,36 +263,19 @@
   dropped from the "should be checked" list.
 
 
-PATCH APPLICATION TO CVS
+PATCH APPLICATION
 
 * Only apply patches that meet the submission guidelines.
 
-* If a patch is large (perhaps more than 100 new/changed lines), tag
-  the repository before and after the change with e.g. before-foo-fix
-  and after-foo-fix.
-
 * If the patch might break something, issue a call for testing on the
   mailinglist.
 
-* Give an appropriate commit message, prefixed with a category name
-  (either the name of the daemon, the library component or the general
-  topic) and a one-line short summary of the change as the first line,
-  suitable for use as a Subject in an email. The ChangeLog entry should
-  suffice as the body of the commit message, if it does not, then the
-  ChangeLog entry itself needs to be corrected. The commit message text
-  should be identical to that added to the ChangeLog message. (One
-  suggestion: when commiting, use your editor to read in the ChangeLog
-  and delete all previous ChangeLogs.) An example:
-  
-  ----------------------------------------------------------------
-  [frob] Defangulator needs to specify frob
-  
-  2012-05-12 Joe Bar <joe@example.com>
-  
-  	* frobinate.c: (frob_lookup) fix NULL dereference
-  	  (defangulate) check whether frob is in state FROB_VALID
-  	  before defangulating.
-  ----------------------------------------------------------------
+* Give an appropriate commit message (see above), and use the --author
+  argument to git-commit, if required, to ensure proper attribution (you
+  should still be listed as committer)
+
+* Immediately after commiting, double-check (with git-log and/or gitk). If
+  there's a small mistake you can easily fix it with 'git commit --amend ..'
 
 * By committing a patch, you are responsible for fixing problems
   resulting from it (or backing it out).
@@ -303,37 +316,14 @@
    zebra_org (http://www.zebra.org/)
    isisd_sf (http://isisd.sf.net/)
 
-[20041105: Is isisd.sf.netf still where isisd word is happening, or is
-the quagga repo now the canonical place?  The last tarball on sf is
-two years old.  --gdt]
+To import code from further sources, e.g. for archival purposes without
+necessarily having to review and/or fix some changeset, create a branch from
+'master':
 
-In order to import source code, the following procedure should be used:
+	git checkout -b archive/foo master
+	<apply changes>
+	git commit -a "Joe Bar <joe@example.com>"
+	git push quagga archive/foo
 
-* Tag the Current Quagga CVS repository:
-
-    cvs tag import_isisd_sf_20031223
-
-* Import the source code into the Quagga's framework. You must not modified
-  this source code. It will be merged later.
-
-    cd dir_isisd
-    export CVSROOT=:pserver:LOGIN@anoncvs.quagga.net:/var/cvsroot 
-    cvs import quagga/isisd isisd_sf isisd_sf_20031223
-  ---COMMENTS---
-    Vendor: [isisd_sf] Sampo's ISISd from Sourceforge
-    Tag: [isisd_sf_20031217] Current CVS release
-  ---
-
-* Update your Quagga's directory:
-
-    cd dir_quagga
-    cvs update -dP
-
-  or
-
-    cvs co -d quagga_isisd quagga
-
-* Merge the code, then commit:
-
-    cvs commit
-
+presuming 'quagga' corresponds to a file in your .git/remotes with
+configuration for the appropriate Quagga.net repository.
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index df1cfb7..15bd8a6 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -616,8 +616,7 @@
 	zlog_debug ("%s passive open", peer->host);
     }
 
-  if (!CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)
-      || bgp_option_check (BGP_OPT_ALWAYS_OPEN))
+  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
     bgp_open_send (peer);
 
   return 0;
diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c
index 3d26890..576e3e0 100644
--- a/bgpd/bgp_snmp.c
+++ b/bgpd/bgp_snmp.c
@@ -23,10 +23,12 @@
 #ifdef HAVE_SNMP
 #ifdef HAVE_NETSNMP
 #include <net-snmp/net-snmp-config.h>
-#endif
+#include <net-snmp/net-snmp-includes.h>
+#else
 #include <asn1.h>
 #include <snmp.h>
 #include <snmp_impl.h>
+#endif
 
 #include "if.h"
 #include "log.h"
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9237cb0..7acf27c 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -279,28 +279,6 @@
   return CMD_SUCCESS;
 }
 
-DEFUN_HIDDEN (bgp_open_accept,
-              bgp_open_accept_cmd,
-              "bgp open-accept",
-              BGP_STR
-              "Send OPEN immediately on accepted connections\n")
-{
-  bgp_option_set (BGP_OPT_ALWAYS_OPEN);
-  return CMD_SUCCESS;
-}
-
-DEFUN_HIDDEN (no_bgp_open_accept,
-              no_bgp_open_accept_cmd,
-              "no bgp open-accept",
-              NO_STR
-              BGP_STR
-              "Send OPEN immediately on accepted connections\n")
-
-{
-  bgp_option_unset (BGP_OPT_ALWAYS_OPEN);
-  return CMD_SUCCESS;
-}
-
 DEFUN (no_synchronization,
        no_synchronization_cmd,
        "no synchronization",
@@ -8842,10 +8820,6 @@
   install_element (CONFIG_NODE, &bgp_config_type_cmd);
   install_element (CONFIG_NODE, &no_bgp_config_type_cmd);
 
-  /* "bgp open-all" commands. */
-  install_element (CONFIG_NODE, &bgp_open_accept_cmd);
-  install_element (CONFIG_NODE, &no_bgp_open_accept_cmd);
-
   /* Dummy commands (Currently not supported) */
   install_element (BGP_NODE, &no_synchronization_cmd);
   install_element (BGP_NODE, &no_auto_summary_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index bda35ae..8eb0d2e 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -81,7 +81,6 @@
     case BGP_OPT_NO_FIB:
     case BGP_OPT_MULTIPLE_INSTANCE:
     case BGP_OPT_CONFIG_CISCO:
-    case BGP_OPT_ALWAYS_OPEN:
       SET_FLAG (bm->options, flag);
       break;
     default:
@@ -101,7 +100,6 @@
       /* Fall through.  */
     case BGP_OPT_NO_FIB:
     case BGP_OPT_CONFIG_CISCO:
-    case BGP_OPT_ALWAYS_OPEN:
       UNSET_FLAG (bm->options, flag);
       break;
     default:
@@ -4912,13 +4910,6 @@
       write++;
     }
 
-  /* BGP Open-Always */
-  if (bgp_option_check (BGP_OPT_ALWAYS_OPEN))
-    {    
-      vty_out (vty, "bgp open-accept%s", VTY_NEWLINE);
-      write++;
-    }
-
   /* BGP configuration. */
   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
     {
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 89dde8f..afe0663 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -59,7 +59,6 @@
 #define BGP_OPT_NO_FIB                   (1 << 0)
 #define BGP_OPT_MULTIPLE_INSTANCE        (1 << 1)
 #define BGP_OPT_CONFIG_CISCO             (1 << 2)
-#define BGP_OPT_ALWAYS_OPEN		 (1 << 3)
 };
 
 /* BGP instance structure.  */
diff --git a/configure.ac b/configure.ac
index 87ec96c..547b686 100755
--- a/configure.ac
+++ b/configure.ac
@@ -206,6 +206,8 @@
 [  --enable-netlink        force to use Linux netlink interface])
 AC_ARG_ENABLE(broken-aliases,
 [  --enable-broken-aliases enable aliases as distinct interfaces for Linux 2.2.X])
+AC_ARG_WITH(crypto,
+[  --without-crypto        do not use libcrypto in SNMP])
 AC_ARG_ENABLE(snmp,
 [  --enable-snmp           enable SNMP support])
 AC_ARG_WITH(libpam,
@@ -1254,29 +1256,19 @@
 dnl check Net-SNMP library
 dnl ------------------
 if test "${enable_snmp}" = "yes"; then
-    LIBS="${LIBS} -lcrypto"
+    if test "$with_crypto" != "no"; then
+        LIBS="${LIBS} -lcrypto";
+    fi
     AC_CHECK_LIB(netsnmp, asn_parse_int,
     	[AC_DEFINE(HAVE_NETSNMP,,Net SNMP) 
     	 AC_DEFINE(HAVE_SNMP,,SNMP)
     	 LIBS="${LIBS} -lnetsnmp"],
     	[AC_MSG_ERROR([--enable-snmp given, but cannot find support for SNMP])])
-    
-    for ac_snmp in /usr/include \
-    		/usr/local/include \
-    		/dev/null; do
-    	test -f "${ac_snmp}/net-snmp/library/asn1.h" && break
-    done
-    
-    case ${ac_snmp} in
-    	/dev/null)
-    		AC_MSG_ERROR([--enable-snmp given, but can not find header])
-    		;;
-    	*)
-    		SNMP_INCLUDES="-I${ac_snmp}/net-snmp"
-    		SNMP_INCLUDES="${SNMP_INCLUDES} -I${ac_snmp}/net-snmp/library"
-    		;;
-    esac
-    
+
+    AC_CHECK_HEADER([net-snmp/net-snmp-config.h],
+        [],
+        [AC_MSG_ERROR([--enable-snmp given, but cannot find net-snmp-config.h])],
+	QUAGGA_INCLUDES)
     AC_SUBST(SNMP_INCLUDES)
 fi
 
diff --git a/lib/smux.c b/lib/smux.c
index 6285c94..4a3696c 100644
--- a/lib/smux.c
+++ b/lib/smux.c
@@ -24,10 +24,12 @@
 #ifdef HAVE_SNMP
 #ifdef HAVE_NETSNMP
 #include <net-snmp/net-snmp-config.h>
-#endif
+#include <net-snmp/net-snmp-includes.h>
+#else
 #include <asn1.h>
 #include <snmp.h>
 #include <snmp_impl.h>
+#endif
 
 #include "log.h"
 #include "thread.h"
diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c
index a1d8d4c..8d9842c 100644
--- a/ospf6d/ospf6_snmp.c
+++ b/ospf6d/ospf6_snmp.c
@@ -25,11 +25,12 @@
 
 #ifdef HAVE_NETSNMP
 #include <net-snmp/net-snmp-config.h>
-#endif /*HAVE_NETSNMP*/
-
+#include <net-snmp/net-snmp-includes.h>
+#else
 #include <asn1.h>
 #include <snmp.h>
 #include <snmp_impl.h>
+#endif
 
 #include "log.h"
 #include "vty.h"
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index a778a50..ed342e7 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -3151,7 +3151,10 @@
   op->length = length;
 
   /* Decide destination address. */
-  op->dst = nbr->address.u.prefix4;
+  if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
+    op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
+  else
+    op->dst = nbr->address.u.prefix4;
 
   /* Add packet to the interface output queue. */
   ospf_packet_add (oi, op);
@@ -3210,7 +3213,10 @@
   op->length = length;
 
   /* Decide destination address. */
-  op->dst = nbr->address.u.prefix4;
+  if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
+    op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
+  else
+    op->dst = nbr->address.u.prefix4;
 
   /* Add packet to the interface output queue. */
   ospf_packet_add (oi, op);
@@ -3326,7 +3332,10 @@
   op->length = length;
 
   /* Decide destination address. */
-  op->dst.s_addr = addr.s_addr;
+  if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
+    op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
+  else
+    op->dst.s_addr = addr.s_addr;
 
   /* Add packet to the interface output queue. */
   ospf_packet_add (oi, op);
@@ -3403,13 +3412,12 @@
   /* Decide destination address. */
   if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
     p.prefix = oi->vl_data->peer_addr;
+  else if (oi->type == OSPF_IFTYPE_POINTOPOINT) 
+     p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
   else if (flag == OSPF_SEND_PACKET_DIRECT)
      p.prefix = nbr->address.u.prefix4;
   else if (oi->state == ISM_DR || oi->state == ISM_Backup)
      p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
-  else if ((oi->type == OSPF_IFTYPE_POINTOPOINT) 
-	   && (flag == OSPF_SEND_PACKET_INDIRECT))
-     p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
   else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
      p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
   else
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index 3a1fa99..50fba75 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -481,7 +481,8 @@
 /* RFC2328 16.1. second stage. */
 void
 ospf_intra_add_stub (struct route_table *rt, struct router_lsa_link *link,
-		     struct vertex *v, struct ospf_area *area)
+		     struct vertex *v, struct ospf_area *area,
+		     int parent_is_root)
 {
   u_int32_t cost;
   struct route_node *rn;
@@ -514,7 +515,20 @@
   if (IS_DEBUG_OSPF_EVENT)
     zlog_debug ("ospf_intra_add_stub(): calculated cost is %d + %d = %d", 
 	       v->distance, ntohs(link->m[0].metric), cost);
-
+  
+  /* PtP links with /32 masks adds host routes to remote, directly
+   * connected hosts, see RFC 2328, 12.4.1.1, Option 1.
+   * Such routes can just be ignored for the sake of tidyness.
+   */
+  if (parent_is_root && link->link_data.s_addr == 0xffffffff &&
+      ospf_if_lookup_by_local_addr (area->ospf, NULL, link->link_id))
+    {
+      if (IS_DEBUG_OSPF_EVENT)
+        zlog_debug ("%s: ignoring host route %s/32 to self.",
+                    __func__, inet_ntoa (link->link_id));
+      return;
+    }
+  
   rn = route_node_get (rt, (struct prefix *) &p);
 
   /* Lookup current routing table. */
diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h
index 351e014..0d37436 100644
--- a/ospfd/ospf_route.h
+++ b/ospfd/ospf_route.h
@@ -140,7 +140,8 @@
 
 extern void ospf_intra_add_stub (struct route_table *,
 				 struct router_lsa_link *, struct vertex *,
-				 struct ospf_area *);
+				 struct ospf_area *,
+				 int parent_is_root);
 
 extern int ospf_route_cmp (struct ospf *, struct ospf_route *,
 			   struct ospf_route *);
diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c
index 6e97260..e6ce1f0 100644
--- a/ospfd/ospf_snmp.c
+++ b/ospfd/ospf_snmp.c
@@ -27,10 +27,12 @@
 #ifdef HAVE_SNMP
 #ifdef HAVE_NETSNMP
 #include <net-snmp/net-snmp-config.h>
-#endif
+#include <net-snmp/net-snmp-includes.h>
+#else
 #include <asn1.h>
 #include <snmp.h>
 #include <snmp_impl.h>
+#endif
 
 #include "if.h"
 #include "log.h"
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 23d45dd..82f0fed 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -946,7 +946,8 @@
 /* Second stage of SPF calculation. */
 static void
 ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,
-                        struct route_table *rt)
+                        struct route_table *rt,
+                        int parent_is_root)
 {
   struct listnode *cnode, *cnnode;
   struct vertex *child;
@@ -981,7 +982,7 @@
                 (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
 
           if (l->m[0].type == LSA_LINK_TYPE_STUB)
-            ospf_intra_add_stub (rt, l, v, area);
+            ospf_intra_add_stub (rt, l, v, area, parent_is_root);
         }
     }
 
@@ -991,8 +992,17 @@
     {
       if (CHECK_FLAG (child->flags, OSPF_VERTEX_PROCESSED))
         continue;
-
-      ospf_spf_process_stubs (area, child, rt);
+      
+      /* the first level of routers connected to the root
+       * should have 'parent_is_root' set, including those 
+       * connected via a network vertex.
+       */
+      if (area->spf == v)
+        parent_is_root = 1;
+      else if (v->type == OSPF_VERTEX_ROUTER)
+        parent_is_root = 0;
+        
+      ospf_spf_process_stubs (area, child, rt, parent_is_root);
 
       SET_FLAG (child->flags, OSPF_VERTEX_PROCESSED);
     }
@@ -1179,7 +1189,7 @@
     }
 
   /* Second stage of SPF calculation procedure's  */
-  ospf_spf_process_stubs (area, area->spf, new_table);
+  ospf_spf_process_stubs (area, area->spf, new_table, 0);
 
   /* Free candidate queue. */
   pqueue_delete (candidate);
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 5307b41..11f12c5 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -3093,7 +3093,7 @@
        "Neighbor list\n"
        "include down status neighbor\n")
 {
-  struct ospf *ospf = vty->index;
+  struct ospf *ospf = ospf_lookup ();
   struct listnode *node;
   struct ospf_interface *oi;
 
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index f302d28..e27f139 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -87,7 +87,6 @@
 ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
 {
   struct interface *ifp;
-  struct ospf *ospf;
 
   ifp = zebra_interface_add_read (zclient->ibuf);
 
@@ -103,9 +102,7 @@
       IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
     }
 
-  ospf = ospf_lookup ();
-  if (ospf != NULL)
-    ospf_if_update (ospf);
+  ospf_if_update (NULL, ifp);
 
 #ifdef HAVE_SNMP
   ospf_snmp_if_update (ifp);
@@ -255,7 +252,6 @@
 ospf_interface_address_add (int command, struct zclient *zclient,
                             zebra_size_t length)
 {
-  struct ospf *ospf;
   struct connected *c;
 
   c = zebra_interface_address_read (command, zclient->ibuf);
@@ -270,9 +266,7 @@
       zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);
     }
 
-  ospf = ospf_lookup ();
-  if (ospf != NULL)
-    ospf_if_update (ospf);
+  ospf_if_update (NULL, c->ifp);
 
 #ifdef HAVE_SNMP
   ospf_snmp_if_update (c->ifp);
@@ -285,7 +279,6 @@
 ospf_interface_address_delete (int command, struct zclient *zclient,
                                zebra_size_t length)
 {
-  struct ospf *ospf;
   struct connected *c;
   struct interface *ifp;
   struct ospf_interface *oi;
@@ -327,10 +320,6 @@
 
   connected_free (c);
 
-  ospf = ospf_lookup ();
-  if (ospf != NULL)
-    ospf_if_update (ospf);
-
   return 0;
 }
 
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index a4c4fac..32580cc 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -68,7 +68,9 @@
 static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
 static void ospf_network_free (struct ospf *, struct ospf_network *);
 static void ospf_area_free (struct ospf_area *);
-static void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
+static void ospf_network_run (struct prefix *, struct ospf_area *);
+static void ospf_network_run_interface (struct prefix *, struct ospf_area *,
+                                        struct interface *);
 static void ospf_finish_final (struct ospf *);
 
 #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
@@ -78,6 +80,7 @@
 {
   struct in_addr router_id, router_id_old;
   struct ospf_interface *oi;
+  struct interface *ifp;
   struct listnode *node;
 
   if (IS_DEBUG_OSPF_EVENT)
@@ -130,7 +133,8 @@
 		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
       
       /* update ospf_interface's */
-      ospf_if_update (ospf);
+      for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
+        ospf_if_update (ospf, ifp);
     }
 }
 
@@ -745,7 +749,7 @@
   area = ospf_area_get (ospf, area_id, ret);
 
   /* Run network config now. */
-  ospf_network_run (ospf, (struct prefix *)p, area);
+  ospf_network_run ((struct prefix *)p, area);
 
   /* Update connected redistribute. */
   if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
@@ -770,6 +774,8 @@
   struct route_node *rn;
   struct ospf_network *network;
   struct external_info *ei;
+  struct listnode *node, *nnode;
+  struct ospf_interface *oi;
 
   rn = route_node_lookup (ospf->networks, (struct prefix *)p);
   if (rn == NULL)
@@ -783,7 +789,31 @@
   rn->info = NULL;
   route_unlock_node (rn);
 
-  ospf_if_update (ospf);
+  /* Find interfaces that not configured already.  */
+  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
+    {
+      int found = 0;
+      struct connected *co = oi->connected;
+      
+      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+        continue;
+      
+      for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
+        {
+          if (rn->info == NULL)
+            continue;
+          
+          if (ospf_network_match_iface(co,&rn->p))
+            {
+              found = 1;
+              route_unlock_node (rn);
+              break;
+            }
+        }
+
+      if (found == 0)
+        ospf_if_free (oi);
+    }
   
   /* Update connected redistribute. */
   if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
@@ -857,73 +887,78 @@
 }
 
 void
-ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
+ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
+                            struct interface *ifp)
+{
+  struct listnode *cnode;
+  struct connected *co;
+  
+  if (memcmp (ifp->name, "VLINK", 5) == 0)
+    return;
+  
+  /* if interface prefix is match specified prefix,
+     then create socket and join multicast group. */
+  for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
+    {
+      struct prefix *addr;
+      
+      if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
+        continue;
+
+      addr = CONNECTED_ID(co);
+
+      if (p->family == co->address->family 
+          && ! ospf_if_is_configured (area->ospf, &(addr->u.prefix4))
+          && ospf_network_match_iface(co,p))
+        {
+           struct ospf_interface *oi;
+            
+            oi = ospf_if_new (area->ospf, ifp, co->address);
+            oi->connected = co;
+            
+            oi->area = area;
+
+            oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
+            oi->output_cost = ospf_if_get_output_cost (oi);
+            
+            /* Add pseudo neighbor. */
+            ospf_nbr_add_self (oi);
+
+            /* Relate ospf interface to ospf instance. */
+            oi->ospf = area->ospf;
+
+            /* update network type as interface flag */
+            /* If network type is specified previously,
+               skip network type setting. */
+            oi->type = IF_DEF_PARAMS (ifp)->type;
+            
+            ospf_area_add_if (oi->area, oi);
+            
+            /* if router_id is not configured, dont bring up
+             * interfaces.
+             * ospf_router_id_update() will call ospf_if_update
+             * whenever r-id is configured instead.
+             */
+            if ((area->ospf->router_id.s_addr != 0)
+                && if_is_operative (ifp)) 
+              ospf_if_up (oi);
+          }
+    }
+}
+
+void
+ospf_network_run (struct prefix *p, struct ospf_area *area)
 {
   struct interface *ifp;
-  struct connected *co;
   struct listnode *node;
 
   /* Schedule Router ID Update. */
-  if (ospf->router_id.s_addr == 0)
-    ospf_router_id_update (ospf);
+  if (area->ospf->router_id.s_addr == 0)
+    ospf_router_id_update (area->ospf);
   
   /* Get target interface. */
   for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
-    {
-      struct listnode *cnode;
-      
-      if (memcmp (ifp->name, "VLINK", 5) == 0)
-	continue;
-	
-      /* if interface prefix is match specified prefix,
-	 then create socket and join multicast group. */
-      for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
-	{
-	  struct prefix *addr;
-	  
-          if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
-            continue;
-
-	  addr = CONNECTED_ID(co);
-
-	  if (p->family == co->address->family 
-	      && ! ospf_if_is_configured (ospf, &(addr->u.prefix4))
-	      && ospf_network_match_iface(co,p))
-	    {
-	       struct ospf_interface *oi;
-		
-		oi = ospf_if_new (ospf, ifp, co->address);
-		oi->connected = co;
-		
-		oi->area = area;
-
-		oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
-		oi->output_cost = ospf_if_get_output_cost (oi);
-		
-		/* Add pseudo neighbor. */
-		ospf_nbr_add_self (oi);
-
-		/* Relate ospf interface to ospf instance. */
-		oi->ospf = ospf;
-
-		/* update network type as interface flag */
-		/* If network type is specified previously,
-		   skip network type setting. */
-		oi->type = IF_DEF_PARAMS (ifp)->type;
-		
-		ospf_area_add_if (oi->area, oi);
-		
-		/* if router_id is not configured, dont bring up
-		 * interfaces.
-                 * ospf_router_id_update() will call ospf_if_update
-                 * whenever r-id is configured instead.
-                 */
-		if ((ospf->router_id.s_addr != 0)
-		    && if_is_operative (ifp)) 
-		  ospf_if_up (oi);
-	      }
-	}
-    }
+    ospf_network_run_interface (p, area, ifp);
 }
 
 void
@@ -954,55 +989,27 @@
 }
 
 void
-ospf_if_update (struct ospf *ospf)
+ospf_if_update (struct ospf *ospf, struct interface *ifp)
 {
   struct route_node *rn;
-  struct listnode *node, *nnode;
   struct ospf_network *network;
   struct ospf_area *area;
-  struct ospf_interface *oi;
+  
+  if (!ospf)
+    ospf = ospf_lookup ();
 
-  if (ospf != NULL)
-    {
-      /* Router-ID must be configured. */
-      if (ospf->router_id.s_addr == 0)
-        return;
-      
-      /* Find interfaces that not configured already.  */
-      for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
-	{
-	  int found = 0;
-	  struct connected *co = oi->connected;
-	  
-	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
-	    continue;
-	  
-	  for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
-	    {
-	      if (rn->info == NULL)
-		continue;
-	      
-	      if (ospf_network_match_iface(co,&rn->p))
-		{
-		  found = 1;
-		  route_unlock_node (rn);
-		  break;
-		}
-	    }
-
-	  if (found == 0)
-	    ospf_if_free (oi);
-	}
-	
-      /* Run each interface. */
-      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 (ospf, network->area_id, network->format);
-	    ospf_network_run (ospf, &rn->p, area);
-	  }
-    }
+  /* Router-ID must be configured. */
+  if (ospf->router_id.s_addr == 0)
+    return;
+  
+  /* Run each netowrk for this interface. */
+  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 (ospf, network->area_id, network->format);
+        ospf_network_run_interface (&rn->p, area, ifp);
+      }
 }
 
 void
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index b618711..6a60e86 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -588,7 +588,7 @@
 extern int ospf_nbr_nbma_poll_interval_unset (struct ospf *, struct in_addr);
 extern void ospf_prefix_list_update (struct prefix_list *);
 extern void ospf_init (void);
-extern void ospf_if_update (struct ospf *);
+extern void ospf_if_update (struct ospf *, struct interface *);
 extern void ospf_ls_upd_queue_empty (struct ospf_interface *);
 extern void ospf_terminate (void);
 extern void ospf_nbr_nbma_if_update (struct ospf *, struct ospf_interface *);
diff --git a/ripd/rip_snmp.c b/ripd/rip_snmp.c
index c1bec76..d02c761 100644
--- a/ripd/rip_snmp.c
+++ b/ripd/rip_snmp.c
@@ -24,10 +24,12 @@
 #ifdef HAVE_SNMP
 #ifdef HAVE_NETSNMP
 #include <net-snmp/net-snmp-config.h>
-#endif
+#include <net-snmp/net-snmp-includes.h>
+#else
 #include <asn1.h>
 #include <snmp.h>
 #include <snmp_impl.h>
+#endif
 
 #include "if.h"
 #include "log.h"
diff --git a/zebra/client_main.c b/zebra/client_main.c
index c319aac..ce01231 100644
--- a/zebra/client_main.c
+++ b/zebra/client_main.c
@@ -1,5 +1,5 @@
 /*
- * $Id: client_main.c,v 1.1 2002/12/13 20:15:30 paul Exp $
+ * $Quagga: $Format:%an, %ai, %h$ $
  *
  * GNU Zebra client test main routine.
  * Copyright (C) 1997 Kunihiro Ishiguro
diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c
index 4536026..7e66e2f 100644
--- a/zebra/zebra_snmp.c
+++ b/zebra/zebra_snmp.c
@@ -24,10 +24,12 @@
 #ifdef HAVE_SNMP
 #ifdef HAVE_NETSNMP
 #include <net-snmp/net-snmp-config.h>
-#endif
+#include <net-snmp/net-snmp-includes.h>
+#else
 #include <asn1.h>
 #include <snmp.h>
 #include <snmp_impl.h>
+#endif
 
 #include "if.h"
 #include "log.h"