Merge remote-tracking branch 'polymorf/master'
diff --git a/HACKING b/HACKING
index 5a20727..0358fed 100644
--- a/HACKING
+++ b/HACKING
@@ -17,6 +17,7 @@
 * STABLE PLATFORMS AND DAEMONS
 * IMPORT OR UPDATE VENDOR SPECIFIC ROUTING PROTOCOLS
 
+
 GUIDELINES FOR HACKING ON QUAGGA
 
 [this is a draft in progress]
@@ -98,6 +99,7 @@
 
 See also below regarding SHARED LIBRARY VERSIONING.
 
+
 COMPILE-TIME CONDITIONAL CODE
 
 Please think very carefully before making code conditional at compile time,
@@ -121,12 +123,13 @@
 Note that the former approach requires ensuring that SOME_SYMBOL will be
 defined (watch your AC_DEFINEs).
 
+
 COMMIT MESSAGES
 
 The commit message should provide:
 
-* A suitable one-line summary as the very first line of the message, in the
-  form:
+* A suitable one-line summary followed by a blank line as the very
+  first line of the message, in the form:
 
   topic: high-level, one line summary
 
@@ -141,12 +144,14 @@
 
 to provide a short description of the general intent of the patch, in terms
 of the problem it solves and how it achieves it, to help reviewers
-understand. 
+understand.
 
+The one-line summary must be limited to 54 characters, and all other
+lines to 72 characters.
 
 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. 
+of which changes are intended, along with a short description for each.
 Some discretion is obviously required.  A C-to-english description is not
 desireable.  For short patches, a per-function/file break-down may be
 redundant.  For longer patches, such a break-down may be essential.
@@ -157,11 +162,13 @@
 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.
 * bar.c: (barinate) Check frob for DOWN state.
 
+Note that the commit message format follows git norms, so that "git
+log --oneline" will have useful output.
 
 HACKING THE BUILD SYSTEM
 
@@ -170,13 +177,14 @@
 
 	- make dist
 	- resulting dist tarball builds
-	- out-of-tree builds 
+	- out-of-tree builds
 
 The quagga.net site relies on make dist to work to generate snapshots. It
 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 apppropriate commit with a release tag (follow existing
@@ -199,7 +207,7 @@
 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. 
+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.
 
@@ -239,23 +247,33 @@
 installed together.
 
 
+GIT COMMIT SUBSMISSION
+
+The preferred method for changes is to provide git commits via a
+publically-accessible git repository.
+
+All content guidelines in PATCH SUBMISSION apply.
+
+
 PATCH SUBMISSION
 
 * Send a clean diff against the 'master' branch of the quagga.git
-  repository, in unified diff format, preferably with the '-p' argument to 
+  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: 
+  minimise changes. E.g:
 
     git diff -up mybranch..remotes/quagga.net/master
 
-  Or by using git-format-patch.
+  It is preferable to use git format-patch, and even more preferred to
+  publish a git repostory.
 
-*  Not doing so is a definite hindrance to patch application.
+  If not using git format-patch, Include the commit message in the email.
 
-* Include NEWS entries as appropriate. 
+* After a commit, code should have comments explaining to the reviewer
+  why it is correct, without reference to history.  The commit message
+  should explain why the change is correct.
 
-* Please, please include an appropriate commit message with any emailed
-  patches. Doing so makes it easier to review a patch, and apply it.
+* Include NEWS entries as appropriate.
 
 * Include only one semantic change or group of changes per patch.
 
diff --git a/HACKING.pending b/HACKING.pending
index 3b923a4..5e0defd 100644
--- a/HACKING.pending
+++ b/HACKING.pending
@@ -19,8 +19,21 @@
 This repository has topic branches for patches intended for inclusion
 in the main quagga tree, named patches/, plus some other branches.
 
+** git remote add balajig http://github.com/balajig/quagga-next.git 
+
+Balaji G has prepared a git repository where a number of patches to
+the list have been stored.
+
+** git remote add mtr http://github.com/tomhenderson/quagga-mtr.git
+
+Tom Henderson of Boeing has created a repository to work on
+multi-topology routing support for OSPF.  Work on this repository
+takes place on the branch mtr, which has a branch point of 0.99.17
+
 * posted patches
 
+** Boeing
+
 Boeing has posted patches
 
   quagga-0.99.9.ospfv3-addressfamilies.patch
@@ -32,3 +45,5 @@
 
 Both patches include functional enhancements as well as support for
 gcc 2.95.
+
+[TODO: Are any of these obsolete with respect to mtr/mtr?]
diff --git a/README.NetBSD b/README.NetBSD
index 9aac4c3..6bbc680 100755
--- a/README.NetBSD
+++ b/README.NetBSD
@@ -20,13 +20,15 @@
 case $1 in
 
     build)
+	# Omitted because it is now default:
+	#   --enable-opaque-lsa
 	./bootstrap.sh
 	LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib" CPPFLAGS="-I/usr/pkg/include" \
     	./configure --prefix=${PREFIX} \
 	    --sysconfdir=/etc/zebra --localstatedir=/var/run/zebra \
 	    --enable-exampledir=${PREFIX}/share/examples/zebra \
 	    --enable-pkgsrcrcdir=${PREFIX}/etc/rc.d \
-	    --enable-opaque-lsa --enable-vtysh
+	    --enable-vtysh
 	${MAKE}
 	;;
 
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index a9602d9..cf93042 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -671,58 +671,80 @@
   return aspath;
 }
 
-/* parse as-segment byte stream in struct assegment */
+/* parse as-segment byte stream in struct assegment
+ *
+ * Returns NULL if the AS_PATH or AS4_PATH is not valid.
+ */
 static struct assegment *
-assegments_parse (struct stream *s, size_t length, int use32bit)
+assegments_parse (struct stream *s, size_t length, int use32bit, int as4_path)
 {
   struct assegment_header segh;
   struct assegment *seg, *prev = NULL, *head = NULL;
-  size_t bytes = 0;
   
-  /* empty aspath (ie iBGP or somesuch) */
-  if (length == 0)
-    return NULL;
+  assert (length > 0);  /* does not expect empty AS_PATH or AS4_PATH    */
   
   if (BGP_DEBUG (as4, AS4_SEGMENT))
     zlog_debug ("[AS4SEG] Parse aspath segment: got total byte length %lu",
 		(unsigned long) length);
-  /* basic checks */
-  if ( (STREAM_READABLE(s) < length)
-      || (STREAM_READABLE(s) < AS_HEADER_SIZE) 
-      || (length % AS16_VALUE_SIZE ))
+
+  /* double check that length does not exceed stream    */
+  if (STREAM_READABLE(s) < length)
     return NULL;
   
-  while ( (STREAM_READABLE(s) > AS_HEADER_SIZE)
-         && (bytes < length))
+  /* deal with each segment in turn                             */
+  while (length > 0)
     {
       int i;
-      int seg_size;
+      size_t seg_size;
       
       /* softly softly, get the header first on its own */
+      if (length < AS_HEADER_SIZE)
+        {
+          assegment_free_all (head);
+          return NULL;
+        }
+      
       segh.type = stream_getc (s);
       segh.length = stream_getc (s);
       
       seg_size = ASSEGMENT_SIZE(segh.length, use32bit);
+                                      /* includes the header bytes */
 
       if (BGP_DEBUG (as4, AS4_SEGMENT))
 	zlog_debug ("[AS4SEG] Parse aspath segment: got type %d, length %d",
                     segh.type, segh.length);
       
-      /* check it.. */
-      if ( ((bytes + seg_size) > length)
-          /* 1771bis 4.3b: seg length contains one or more */
-          || (segh.length == 0) 
-          /* Paranoia in case someone changes type of segment length.
-           * Shift both values by 0x10 to make the comparison operate
-           * on more, than 8 bits (otherwise it's a warning, bug #564).
-           */
-          || ((sizeof segh.length > 1) && (0x10 + segh.length > 0x10 + AS_SEGMENT_MAX)) )
+      switch (segh.type)
         {
-          if (head)
-            assegment_free_all (head);
+          case AS_SEQUENCE:
+          case AS_SET:
+            break ;
+
+          case AS_CONFED_SEQUENCE:
+          case AS_CONFED_SET:
+            if (!as4_path)
+              break ;
+              /* RFC4893 3: "invalid for the AS4_PATH attribute"            */
+              /* fall through */
+
+          default:    /* reject unknown or invalid AS_PATH segment types  */
+            seg_size = 0 ;
+        }
+     
+     /* Stop now if segment is not valid (discarding anything collected to date)
+      *
+      * RFC4271 4.3, Path Attributes, b) AS_PATH:
+      *
+      *   "path segment value field contains one or more AS numbers"
+           */
+      if ((seg_size == 0) || (seg_size > length) || (segh.length == 0))
+        {
+          assegment_free_all (head);
           return NULL;
         }
       
+      length -= seg_size ;
+      
       /* now its safe to trust lengths */
       seg = assegment_new (segh.type, segh.length);
       
@@ -734,11 +756,9 @@
       for (i = 0; i < segh.length; i++)
 	seg->as[i] = (use32bit) ? stream_getl (s) : stream_getw (s);
 
-      bytes += seg_size;
-      
       if (BGP_DEBUG (as4, AS4_SEGMENT))
-	zlog_debug ("[AS4SEG] Parse aspath segment: Bytes now: %lu",
-	            (unsigned long) bytes);
+	zlog_debug ("[AS4SEG] Parse aspath segment: length left: %lu",
+	            (unsigned long) length);
       
       prev = seg;
     }
@@ -746,30 +766,42 @@
   return assegment_normalise (head);
 }
 
-/* AS path parse function.  pnt is a pointer to byte stream and length
-   is length of byte stream.  If there is same AS path in the the AS
-   path hash then return it else make new AS path structure. */
+/* AS path parse function -- parses AS_PATH and AS4_PATH attributes
+ *
+ * Requires: s        -- stream, currently positioned before first segment
+ *                       of AS_PATH or AS4_PATH (ie after attribute header)
+ *           length   -- length of the value of the AS_PATH or AS4_PATH
+ *           use32bit -- true <=> 4Byte ASN, otherwise 2Byte ASN
+ *           as4_path -- true <=> AS4_PATH, otherwise AS_PATH
+ *
+ * Returns: if valid: address of struct aspath in the hash of known aspaths,
+ *                    with reference count incremented.
+ *              else: NULL
+ *
+ * NB: empty AS path (length == 0) is valid.  The returned struct aspath will
+ *     have segments == NULL and str == zero length string (unique).
+ */
 struct aspath *
-aspath_parse (struct stream *s, size_t length, int use32bit)
+aspath_parse (struct stream *s, size_t length, int use32bit, int as4_path)
 {
   struct aspath as;
   struct aspath *find;
 
-  /* If length is odd it's malformed AS path. */
-  /* Nit-picking: if (use32bit == 0) it is malformed if odd,
-   * otherwise its malformed when length is larger than 2 and (length-2) 
-   * is not dividable by 4.
-   * But... this time we're lazy
-   */
-  if (length % AS16_VALUE_SIZE )
-    return NULL;
-
+  /* Parse each segment and construct normalised list of struct assegment */
   memset (&as, 0, sizeof (struct aspath));
-  as.segments = assegments_parse (s, length, use32bit);
+  if (length != 0)
+    {
+      as.segments = assegments_parse (s, length, use32bit, as4_path);
+
+      if (as.segments == NULL)
+        return NULL ;   /* Invalid AS_PATH or AS4_PATH  */
+    } ;
   
   /* If already same aspath exist then return it. */
   find = hash_get (ashash, &as, aspath_hash_alloc);
   
+  assert(find) ;        /* valid aspath, so must find or create */
+  
   /* aspath_hash_alloc dupes segments too. that probably could be
    * optimised out.
    */
@@ -777,8 +809,6 @@
   if (as.str)
     XFREE (MTYPE_AS_STR, as.str);
   
-  if (! find)
-    return NULL;
   find->refcnt++;
 
   return find;
@@ -1602,7 +1632,7 @@
 struct aspath *
 aspath_empty (void)
 {
-  return aspath_parse (NULL, 0, 1); /* 32Bit ;-) */
+  return aspath_parse (NULL, 0, 1, 0); /* 32Bit ;-) not AS4_PATH */
 }
 
 struct aspath *
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
index b8a5dfa..d63b914 100644
--- a/bgpd/bgp_aspath.h
+++ b/bgpd/bgp_aspath.h
@@ -65,7 +65,7 @@
 /* Prototypes. */
 extern void aspath_init (void);
 extern void aspath_finish (void);
-extern struct aspath *aspath_parse (struct stream *, size_t, int);
+extern struct aspath *aspath_parse (struct stream *, size_t, int, int);
 extern struct aspath *aspath_dup (struct aspath *);
 extern struct aspath *aspath_aggregate (struct aspath *, struct aspath *);
 extern struct aspath *aspath_prepend (struct aspath *, struct aspath *);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 5e7536a..01598c8 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -28,6 +28,7 @@
 #include "stream.h"
 #include "log.h"
 #include "hash.h"
+#include "jhash.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_attr.h"
@@ -116,18 +117,9 @@
 static unsigned int
 cluster_hash_key_make (void *p)
 {
-  struct cluster_list * cluster = (struct cluster_list *) p;
-  unsigned int key = 0;
-  int length;
-  caddr_t pnt;
+  const struct cluster_list *cluster = p;
 
-  length = cluster->length;
-  pnt = (caddr_t) cluster->list;
-  
-  while (length)
-    key += pnt[--length];
-
-  return key;
+  return jhash(cluster->list, cluster->length, 0);
 }
 
 static int
@@ -258,18 +250,9 @@
 static unsigned int
 transit_hash_key_make (void *p)
 {
-  struct transit * transit = (struct transit *) p;
-  unsigned int key = 0;
-  int length;
-  caddr_t pnt;
+  const struct transit * transit = p;
 
-  length = transit->length;
-  pnt = (caddr_t) transit->val;
-  
-  while (length)
-    key += pnt[--length];
-
-  return key;
+  return jhash(transit->val, transit->length, 0);
 }
 
 static int
@@ -352,51 +335,46 @@
 unsigned int
 attrhash_key_make (void *p)
 {
-  struct attr * attr = (struct attr *) p;
-  unsigned int key = 0;
+  const struct attr * attr = (struct attr *) p;
+  uint32_t key = 0;
+#define MIX(val)	key = jhash_1word(val, key)
+
+  MIX(attr->origin);
+  MIX(attr->nexthop.s_addr);
+  MIX(attr->med);
+  MIX(attr->local_pref);
 
   key += attr->origin;
   key += attr->nexthop.s_addr;
   key += attr->med;
   key += attr->local_pref;
-  if (attr->pathlimit.as)
-    {
-      key += attr->pathlimit.ttl;
-      key += attr->pathlimit.as;
-    }
   
   if (attr->extra)
     {
-      key += attr->extra->aggregator_as;
-      key += attr->extra->aggregator_addr.s_addr;
-      key += attr->extra->weight;
-      key += attr->extra->mp_nexthop_global_in.s_addr;
+      MIX(attr->extra->aggregator_as);
+      MIX(attr->extra->aggregator_addr.s_addr);
+      MIX(attr->extra->weight);
+      MIX(attr->extra->mp_nexthop_global_in.s_addr);
     }
   
   if (attr->aspath)
-    key += aspath_key_make (attr->aspath);
+    MIX(aspath_key_make (attr->aspath));
   if (attr->community)
-    key += community_hash_make (attr->community);
+    MIX(community_hash_make (attr->community));
   
   if (attr->extra)
     {
       if (attr->extra->ecommunity)
-        key += ecommunity_hash_make (attr->extra->ecommunity);
+        MIX(ecommunity_hash_make (attr->extra->ecommunity));
       if (attr->extra->cluster)
-        key += cluster_hash_key_make (attr->extra->cluster);
+        MIX(cluster_hash_key_make (attr->extra->cluster));
       if (attr->extra->transit)
-        key += transit_hash_key_make (attr->extra->transit);
+        MIX(transit_hash_key_make (attr->extra->transit));
 
 #ifdef HAVE_IPV6
-      {
-        int i;
-        
-        key += attr->extra->mp_nexthop_len;
-        for (i = 0; i < 16; i++)
-          key += attr->extra->mp_nexthop_global.s6_addr[i];
-        for (i = 0; i < 16; i++)
-          key += attr->extra->mp_nexthop_local.s6_addr[i];
-      }
+      MIX(attr->extra->mp_nexthop_len);
+      key = jhash(attr->extra->mp_nexthop_global.s6_addr, 16, key);
+      key = jhash(attr->extra->mp_nexthop_local.s6_addr, 16, key);
 #endif /* HAVE_IPV6 */
     }
 
@@ -415,9 +393,7 @@
       && attr1->aspath == attr2->aspath
       && attr1->community == attr2->community
       && attr1->med == attr2->med
-      && attr1->local_pref == attr2->local_pref
-      && attr1->pathlimit.ttl == attr2->pathlimit.ttl
-      && attr1->pathlimit.as == attr2->pathlimit.as)
+      && attr1->local_pref == attr2->local_pref)
     {
       const struct attr_extra *ae1 = attr1->extra;
       const struct attr_extra *ae2 = attr2->extra;
@@ -704,43 +680,6 @@
     }
 }
 
-/* Parse AS_PATHLIMIT attribute in an UPDATE */
-static int
-bgp_attr_aspathlimit (struct peer *peer, bgp_size_t length,
-                      struct attr *attr, u_char flag, u_char *startp)
-{
-  bgp_size_t total;
-  
-  total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
-  
-  if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
-       || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL))
-    {
-      zlog (peer->log, LOG_ERR, 
-	    "AS-Pathlimit attribute flag isn't transitive %d", flag);
-      bgp_notify_send_with_data (peer, 
-				 BGP_NOTIFY_UPDATE_ERR, 
-				 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
-				 startp, total);
-      return -1;
-    }
-  
-  if (length != 5)
-    {
-      zlog (peer->log, LOG_ERR, 
-	    "AS-Pathlimit length, %u, is not 5", length);
-      bgp_notify_send_with_data (peer, 
-				 BGP_NOTIFY_UPDATE_ERR, 
-				 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
-				 startp, total);
-      return -1;
-    }
-  
-  attr->pathlimit.ttl = stream_getc (BGP_INPUT(peer));
-  attr->pathlimit.as = stream_getl (BGP_INPUT(peer));
-  attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
-  return 0;
-}
 /* Get origin attribute of the update message. */
 static int
 bgp_attr_origin (struct peer *peer, bgp_size_t length, 
@@ -807,54 +746,78 @@
 
   return 0;
 }
-
-/* Parse AS path information.  This function is wrapper of
-   aspath_parse. */
-static int
+/* Parse AS path information.  This function is wrapper of aspath_parse.
+ *
+ * Parses AS_PATH or AS4_PATH.
+ *
+ * Returns: if valid: address of struct aspath in the hash of known aspaths,
+ *                    with reference count incremented.
+ *              else: NULL
+ *
+ * NB: empty AS path (length == 0) is valid.  The returned struct aspath will
+ *     have segments == NULL and str == zero length string (unique).
+ */
+static struct aspath *
 bgp_attr_aspath (struct peer *peer, bgp_size_t length, 
-		 struct attr *attr, u_char flag, u_char *startp)
+		 struct attr *attr, u_char flag, u_char *startp, int as4_path)
 {
-  bgp_size_t total;
+  u_char require ;
+  struct aspath *asp ;
 
-  total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
+  /* Check the attribute flags                                          */
+  require = as4_path ? BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
+                     :                          BGP_ATTR_FLAG_TRANS ;
 
-  /* Flag check. */
-  if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)
-      || ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
+  if ((flag & (BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS)) != require)
     {
+      const char* path_type ;
+      bgp_size_t total;
+
+      path_type = as4_path ? "AS4_PATH" : "AS_PATH" ;
+
+      if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS))
       zlog (peer->log, LOG_ERR, 
-	    "As-Path attribute flag isn't transitive %d", flag);
+            "%s attribute flag isn't transitive %d", path_type, flag) ;
+
+      if ((flag & BGP_ATTR_FLAG_OPTIONAL) != (require & BGP_ATTR_FLAG_OPTIONAL))
+        zlog (peer->log, LOG_ERR,
+            "%s attribute flag must %sbe optional %d", path_type,
+            (flag & BGP_ATTR_FLAG_OPTIONAL) ? "not " : "", flag) ;
+
+      total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
+
       bgp_notify_send_with_data (peer, 
 				 BGP_NOTIFY_UPDATE_ERR, 
 				 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
 				 startp, total);
-      return -1;
-    }
 
-  /*
-   * peer with AS4 => will get 4Byte ASnums
-   * otherwise, will get 16 Bit
+      return NULL ;
+    } ;
+
+  /* Parse the AS_PATH/AS4_PATH body.
+   *
+   * For AS_PATH  peer with AS4 => 4Byte ASN otherwise 2Byte ASN
+   *     AS4_PATH 4Byte ASN
    */
-  attr->aspath = aspath_parse (peer->ibuf, length, 
-                               CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV));
+  asp = aspath_parse (peer->ibuf, length,
+               as4_path || CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV), as4_path) ;
 
-  /* In case of IBGP, length will be zero. */
-  if (! attr->aspath)
+  if (asp != NULL)
+    {
+      attr->flag |= ATTR_FLAG_BIT (as4_path ? BGP_ATTR_AS4_PATH
+                                            : BGP_ATTR_AS_PATH) ;
+    }
+  else
     {
       zlog (peer->log, LOG_ERR, "Malformed AS path length is %d", length);
+
+      /* TODO: should BGP_NOTIFY_UPDATE_MAL_AS_PATH be sent for AS4_PATH ??  */
       bgp_notify_send (peer, 
 		       BGP_NOTIFY_UPDATE_ERR, 
 		       BGP_NOTIFY_UPDATE_MAL_AS_PATH);
-      return -1;
-    }
+    } ;
 
-  /* Forward pointer. */
-/*  stream_forward_getp (peer->ibuf, length);*/
-
-  /* Set aspath attribute flag. */
-  attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
-
-  return 0;
+  return asp ;
 }
 
 static int bgp_attr_aspath_check( struct peer *peer, 
@@ -912,21 +875,6 @@
 
 }
 
-/* Parse AS4 path information.  This function is another wrapper of
-   aspath_parse. */
-static int
-bgp_attr_as4_path (struct peer *peer, bgp_size_t length, 
-		 struct attr *attr, struct aspath **as4_path)
-{
-  *as4_path = aspath_parse (peer->ibuf, length, 1);
-
-  /* Set aspath attribute flag. */
-  if (as4_path)
-    attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
-
-  return 0;
-}
-
 /* Nexthop attribute. */
 static int
 bgp_attr_nexthop (struct peer *peer, bgp_size_t length, 
@@ -1226,13 +1174,16 @@
       attr->community = NULL;
       return 0;
     }
-  else
-    {
-      attr->community = 
-        community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length);
-      stream_forward_getp (peer->ibuf, length);
-    }
+  
+  attr->community =
+    community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length);
+  
+  /* XXX: fix community_parse to use stream API and remove this */
+  stream_forward_getp (peer->ibuf, length);
 
+  if (!attr->community)
+    return -1;
+  
   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
 
   return 0;
@@ -1292,8 +1243,8 @@
 bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
 		    struct bgp_nlri *mp_update)
 {
-  u_int16_t afi;
-  u_char safi;
+  afi_t afi;
+  safi_t safi;
   bgp_size_t nlri_len;
   size_t start;
   int ret;
@@ -1427,8 +1378,8 @@
 		      struct bgp_nlri *mp_withdraw)
 {
   struct stream *s;
-  u_int16_t afi;
-  u_char safi;
+  afi_t afi;
+  safi_t safi;
   u_int16_t withdraw_len;
   int ret;
 
@@ -1469,13 +1420,18 @@
     {
       if (attr->extra)
         attr->extra->ecommunity = NULL;
+      /* Empty extcomm doesn't seem to be invalid per se */
+      return 0;
     }
-  else
-    {
-      (bgp_attr_extra_get (attr))->ecommunity = 
-        ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
-      stream_forward_getp (peer->ibuf, length);
-    }
+
+  (bgp_attr_extra_get (attr))->ecommunity =
+    ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
+  /* XXX: fix ecommunity_parse to use stream API */
+  stream_forward_getp (peer->ibuf, length);
+  
+  if (!attr->extra->ecommunity)
+    return -1;
+  
   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
 
   return 0;
@@ -1657,10 +1613,12 @@
 	  ret = bgp_attr_origin (peer, length, attr, flag, startp);
 	  break;
 	case BGP_ATTR_AS_PATH:
-	  ret = bgp_attr_aspath (peer, length, attr, flag, startp);
+          attr->aspath = bgp_attr_aspath (peer, length, attr, flag, startp, 0);
+          ret = attr->aspath ? 0 : -1 ;
 	  break;
 	case BGP_ATTR_AS4_PATH:
-	  ret = bgp_attr_as4_path (peer, length, attr, &as4_path );
+          as4_path = bgp_attr_aspath (peer, length, attr, flag, startp, 1);
+          ret = as4_path  ? 0 : -1 ;
 	  break;
 	case BGP_ATTR_NEXT_HOP:	
 	  ret = bgp_attr_nexthop (peer, length, attr, flag, startp);
@@ -1698,9 +1656,6 @@
 	case BGP_ATTR_EXT_COMMUNITIES:
 	  ret = bgp_attr_ext_communities (peer, length, attr, flag);
 	  break;
-        case BGP_ATTR_AS_PATHLIMIT:
-          ret = bgp_attr_aspathlimit (peer, length, attr, flag, startp);
-          break;
 	default:
 	  ret = bgp_attr_unknown (peer, attr, flag, type, length, startp);
 	  break;
@@ -2255,24 +2210,6 @@
       stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
     }
   
-  /* AS-Pathlimit */
-  if (attr->pathlimit.ttl)
-    {
-      u_int32_t as = attr->pathlimit.as;
-      
-      /* should already have been done in announce_check(), 
-       * but just in case..
-       */
-      if (!as)
-        as = peer->local_as;
-      
-      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
-      stream_putc (s, BGP_ATTR_AS_PATHLIMIT);
-      stream_putc (s, 5);
-      stream_putc (s, attr->pathlimit.ttl);
-      stream_putl (s, as);
-    }
-  
   /* Unknown transit attribute. */
   if (attr->extra && attr->extra->transit)
     stream_put (s, attr->extra->transit->val, attr->extra->transit->length);
@@ -2484,16 +2421,6 @@
     }
 #endif /* HAVE_IPV6 */
 
-  /* AS-Pathlimit */
-  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT))
-    {
-      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
-      stream_putc (s, BGP_ATTR_AS_PATHLIMIT);
-      stream_putc (s, 5);
-      stream_putc (s, attr->pathlimit.ttl);
-      stream_putl (s, attr->pathlimit.as);
-    }
-
   /* Return total size of attribute. */
   len = stream_get_endp (s) - cp - 2;
   stream_putw_at (s, cp, len);
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index ed8753b..af9dcf5 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -110,12 +110,6 @@
   u_int32_t med;
   u_int32_t local_pref;
   
-  /* AS-Pathlimit */
-  struct {
-    u_int32_t as;
-    u_char ttl;
-  } pathlimit;
-  
   /* Path origin attribute */
   u_char origin;
 };
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c
index ba059f8..a513883 100644
--- a/bgpd/bgp_damp.c
+++ b/bgpd/bgp_damp.c
@@ -407,14 +407,10 @@
   damp->reuse_list = XCALLOC (MTYPE_BGP_DAMP_ARRAY, 
 			      damp->reuse_list_size 
 			      * sizeof (struct bgp_reuse_node *));
-  memset (damp->reuse_list, 0x00, 
-          damp->reuse_list_size * sizeof (struct bgp_reuse_node *));  
 
   /* Reuse-array computations */
-  damp->reuse_index = XMALLOC (MTYPE_BGP_DAMP_ARRAY, 
+  damp->reuse_index = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
 			       sizeof(int) * damp->reuse_index_size);
-  memset (damp->reuse_index, 0x00,
-          damp->reuse_list_size * sizeof (int));
 
   reuse_max_ratio = (double)damp->ceiling/damp->reuse_limit;
   j = (exp((double)damp->max_suppress_time/damp->half_life) * log10(2.0));
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index c2077a5..26b35df 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -331,7 +331,6 @@
        undebug_bgp_as4_cmd,
        "undebug bgp as4",
        UNDEBUG_STR
-       DEBUG_STR
        BGP_STR
        "BGP AS4 actions\n")
 
@@ -340,6 +339,7 @@
        "debug bgp as4 segment",
        DEBUG_STR
        BGP_STR
+       "BGP AS4 actions\n"
        "BGP AS4 aspath segment handling\n")
 {
   if (vty->node == CONFIG_NODE)
@@ -358,6 +358,7 @@
        NO_STR
        DEBUG_STR
        BGP_STR
+       "BGP AS4 actions\n"
        "BGP AS4 aspath segment handling\n")
 {
   if (vty->node == CONFIG_NODE)
@@ -374,8 +375,8 @@
        undebug_bgp_as4_segment_cmd,
        "undebug bgp as4 segment",
        UNDEBUG_STR
-       DEBUG_STR
        BGP_STR
+       "BGP AS4 actions\n"
        "BGP AS4 aspath segment handling\n")
 
 DEFUN (debug_bgp_fsm,
@@ -417,7 +418,6 @@
        undebug_bgp_fsm_cmd,
        "undebug bgp fsm",
        UNDEBUG_STR
-       DEBUG_STR
        BGP_STR
        "Finite State Machine\n")
 
@@ -715,7 +715,6 @@
        undebug_bgp_zebra_cmd,
        "undebug bgp zebra",
        UNDEBUG_STR
-       DEBUG_STR
        BGP_STR
        "BGP Zebra messages\n")
 
diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c
index 8087a40..edb725a 100644
--- a/bgpd/bgp_dump.c
+++ b/bgpd/bgp_dump.c
@@ -356,7 +356,11 @@
           stream_putw(obuf, info->peer->table_dump_index);
 
           /* Originated */
+#ifdef HAVE_CLOCK_MONOTONIC
+          stream_putl (obuf, time(NULL) - (bgp_clock() - info->uptime));
+#else
           stream_putl (obuf, info->uptime);
+#endif /* HAVE_CLOCK_MONOTONIC */
 
           /* Dump attribute. */
           /* Skip prefix & AFI/SAFI for MP_NLRI */
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 9d14683..1a460c6 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -243,7 +243,15 @@
   if (retain_mode)
     if_add_hook (IF_DELETE_HOOK, NULL);
   for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
-    if_delete (ifp);
+    {
+      struct listnode *c_node, *c_nnode;
+      struct connected *c;
+
+      for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
+        bgp_connected_delete (c);
+
+      if_delete (ifp);
+    }
   list_free (iflist);
 
   /* reverse bgp_attr_init */
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 9e3427d..570cc3b 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -30,6 +30,7 @@
 #include "command.h"
 #include "privs.h"
 #include "linklist.h"
+#include "network.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_fsm.h"
@@ -150,6 +151,7 @@
       zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno));
       return -1;
     }
+  set_nonblocking (bgp_sock);
 
   if (BGP_DEBUG (events, EVENTS))
     zlog_debug ("[Event] BGP connection from host %s", inet_sutop (&su, buf));
@@ -172,8 +174,11 @@
     }
 
   /* In case of peer is EBGP, we should set TTL for this connection.  */
-  if (peer_sort (peer1) == BGP_PEER_EBGP)
+  if (peer_sort (peer1) == BGP_PEER_EBGP) {
     sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl);
+    if (peer1->gtsm_hops)
+      sockopt_minttl (peer1->su.sa.sa_family, bgp_sock, MAXTTL + 1 - peer1->gtsm_hops);
+  }
 
   /* Make dummy peer until read Open packet. */
   if (BGP_DEBUG (events, EVENTS))
@@ -313,8 +318,11 @@
     return -1;
 
   /* If we can get socket for the peer, adjest TTL and make connection. */
-  if (peer_sort (peer) == BGP_PEER_EBGP)
+  if (peer_sort (peer) == BGP_PEER_EBGP) {
     sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
+    if (peer->gtsm_hops)
+      sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - peer->gtsm_hops);
+  }
 
   sockopt_reuseaddr (peer->fd);
   sockopt_reuseport (peer->fd);
@@ -461,7 +469,10 @@
 	  zlog_err ("socket: %s", safe_strerror (errno));
 	  continue;
 	}
-
+	
+      /* if we intend to implement ttl-security, this socket needs ttl=255 */
+      sockopt_ttl (ainfo->ai_family, sock, MAXTTL);
+      
       ret = bgp_listener (sock, ainfo->ai_addr, ainfo->ai_addrlen);
       if (ret == 0)
 	++count;
@@ -494,6 +505,9 @@
       return sock;
     }
 
+  /* if we intend to implement ttl-security, this socket needs ttl=255 */
+  sockopt_ttl (AF_INET, sock, MAXTTL);
+
   memset (&sin, 0, sizeof (struct sockaddr_in));
   sin.sin_family = AF_INET;
   sin.sin_port = htons (port);
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 0cde665..719cb96 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -276,6 +276,8 @@
 
 		  if (bnc->metric != oldbnc->metric)
 		    bnc->metricchanged = 1;
+
+                  bgp_unlock_node (oldrn);
 		}
 	    }
 	}
@@ -365,6 +367,8 @@
 
 		  if (bnc->metric != oldbnc->metric)
 		    bnc->metricchanged = 1;
+
+                  bgp_unlock_node (oldrn);
 		}
 	    }
 	}
@@ -571,7 +575,7 @@
 	}
       else
 	{
-	  bc = XCALLOC (0, sizeof (struct bgp_connected_ref));
+	  bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
 	  bc->refcnt = 1;
 	  rn->info = bc;
 	}
@@ -596,7 +600,7 @@
 	}
       else
 	{
-	  bc = XCALLOC (0, sizeof (struct bgp_connected_ref));
+	  bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
 	  bc->refcnt = 1;
 	  rn->info = bc;
 	}
@@ -636,7 +640,7 @@
       bc->refcnt--;
       if (bc->refcnt == 0)
 	{
-	  XFREE (0, bc);
+	  XFREE (MTYPE_BGP_CONN, bc);
 	  rn->info = NULL;
 	}
       bgp_unlock_node (rn);
@@ -662,7 +666,7 @@
       bc->refcnt--;
       if (bc->refcnt == 0)
 	{
-	  XFREE (0, bc);
+	  XFREE (MTYPE_BGP_CONN, bc);
 	  rn->info = NULL;
 	}
       bgp_unlock_node (rn);
@@ -1136,11 +1140,15 @@
   rn1 = bgp_node_match (bgp_connected_table[AFI_IP], &p1);
   if (! rn1)
     return 0;
+  bgp_unlock_node (rn1);
   
   rn2 = bgp_node_match (bgp_connected_table[AFI_IP], &p2);
   if (! rn2)
     return 0;
+  bgp_unlock_node (rn2);
 
+  /* This is safe, even with above unlocks, since we are just
+     comparing pointers to the objects, not the objects themselves. */
   if (rn1 == rn2)
     return 1;
 
@@ -1316,6 +1324,9 @@
 void
 bgp_scan_finish (void)
 {
+  /* Only the current one needs to be reset. */
+  bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP]);
+
   bgp_table_unlock (cache1_table[AFI_IP]);
   cache1_table[AFI_IP] = NULL;
 
@@ -1326,6 +1337,9 @@
   bgp_connected_table[AFI_IP] = NULL;
 
 #ifdef HAVE_IPV6
+  /* Only the current one needs to be reset. */
+  bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP6]);
+
   bgp_table_unlock (cache1_table[AFI_IP6]);
   cache1_table[AFI_IP6] = NULL;
 
diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h
index 59265dc..2b1382d 100644
--- a/bgpd/bgp_open.h
+++ b/bgpd/bgp_open.h
@@ -31,9 +31,9 @@
 /* Generic MP capability data */
 struct capability_mp_data
 {
-  u_int16_t afi;
+  afi_t afi;
   u_char reserved;
-  u_char safi;
+  safi_t safi;
 };
 
 #pragma pack(1)
@@ -55,8 +55,8 @@
 
 struct graceful_restart_af
 {
-  u_int16_t afi;
-  u_char safi;
+  afi_t afi;
+  safi_t safi;
   u_char flag;
 };
 
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index b29bc1f..ed2cb73 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -177,10 +177,11 @@
 	  
 	  if (rn->prn)
 	    prd = (struct prefix_rd *) &rn->prn->p;
-          if (binfo && binfo->extra)
+          if (binfo)
             {
-              tag = binfo->extra->tag;
               from = binfo->peer;
+              if (binfo->extra)
+                tag = binfo->extra->tag;
             }
           
 	  bgp_packet_set_marker (s, BGP_MSG_UPDATE);
@@ -597,7 +598,6 @@
   struct stream *s; 
   int num;
   unsigned int count = 0;
-  int write_errno;
 
   /* Yes first of all get peer pointer. */
   peer = THREAD_ARG (thread);
@@ -610,46 +610,37 @@
       return 0;
     }
 
-    /* Nonblocking write until TCP output buffer is full.  */
-  while (1)
+  s = bgp_write_packet (peer);
+  if (!s)
+    return 0;	/* nothing to send */
+
+  sockopt_cork (peer->fd, 1);
+
+  /* Nonblocking write until TCP output buffer is full.  */
+  do
     {
       int writenum;
-      int val;
-
-      s = bgp_write_packet (peer);
-      if (! s)
-	return 0;
-      
-      /* XXX: FIXME, the socket should be NONBLOCK from the start
-       * status shouldnt need to be toggled on each write
-       */
-      val = fcntl (peer->fd, F_GETFL, 0);
-      fcntl (peer->fd, F_SETFL, val|O_NONBLOCK);
 
       /* Number of bytes to be sent.  */
       writenum = stream_get_endp (s) - stream_get_getp (s);
 
       /* Call write() system call.  */
       num = write (peer->fd, STREAM_PNT (s), writenum);
-      write_errno = errno;
-      fcntl (peer->fd, F_SETFL, val);
-      if (num <= 0)
+      if (num < 0)
 	{
-	  /* Partial write. */
-	  if (write_errno == EWOULDBLOCK || write_errno == EAGAIN)
-	      break;
+	  /* write failed either retry needed or error */
+	  if (ERRNO_IO_RETRY(errno))
+		break;
 
-	  BGP_EVENT_ADD (peer, TCP_fatal_error);
+          BGP_EVENT_ADD (peer, TCP_fatal_error);
 	  return 0;
 	}
+
       if (num != writenum)
 	{
+	  /* Partial write */
 	  stream_forward_getp (s, num);
-
-	  if (write_errno == EAGAIN)
-	    break;
-
-	  continue;
+	  break;
 	}
 
       /* Retrieve BGP packet type. */
@@ -690,13 +681,14 @@
 
       /* OK we send packet so delete it. */
       bgp_packet_delete (peer);
-
-      if (++count >= BGP_WRITE_PACKET_MAX)
-	break;
     }
+  while (++count < BGP_WRITE_PACKET_MAX &&
+	 (s = bgp_write_packet (peer)) != NULL);
   
   if (bgp_write_proceed (peer))
     BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
+  else
+    sockopt_cork (peer->fd, 0);
   
   return 0;
 }
@@ -705,7 +697,7 @@
 static int
 bgp_write_notify (struct peer *peer)
 {
-  int ret;
+  int ret, val;
   u_char type;
   struct stream *s; 
 
@@ -715,7 +707,10 @@
     return 0;
   assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
 
-  /* I'm not sure fd is writable. */
+  /* Put socket in blocking mode. */
+  val = fcntl (peer->fd, F_GETFL, 0);
+  fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK);
+
   ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
   if (ret <= 0)
     {
@@ -1884,12 +1879,6 @@
       bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
     UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
 
-  /* Also apply to Unsupported Capability until remote router support
-     capability. */
-  if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
-      bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)
-    UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
-
   BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
 }
 
@@ -2016,8 +2005,14 @@
 
 	      while (p_pnt < p_end)
 		{
+                  /* If the ORF entry is malformed, want to read as much of it
+                   * as possible without going beyond the bounds of the entry,
+                   * to maximise debug information.
+                   */
+		  int ok;
 		  memset (&orfp, 0, sizeof (struct orf_prefix));
 		  common = *p_pnt++;
+		  /* after ++: p_pnt <= p_end */
 		  if (common & ORF_COMMON_PART_REMOVE_ALL)
 		    {
 		      if (BGP_DEBUG (normal, NORMAL))
@@ -2025,34 +2020,60 @@
 		      prefix_bgp_orf_remove_all (name);
 		      break;
 		    }
-		  memcpy (&seq, p_pnt, sizeof (u_int32_t));
-		  p_pnt += sizeof (u_int32_t);
-		  orfp.seq = ntohl (seq);
-		  orfp.ge = *p_pnt++;
-		  orfp.le = *p_pnt++;
-		  orfp.p.prefixlen = *p_pnt++;
-		  orfp.p.family = afi2family (afi);
-		  psize = PSIZE (orfp.p.prefixlen);
-		  memcpy (&orfp.p.u.prefix, p_pnt, psize);
+		  ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
+		  if (!ok)
+		    {
+		      memcpy (&seq, p_pnt, sizeof (u_int32_t));
+                      p_pnt += sizeof (u_int32_t);
+                      orfp.seq = ntohl (seq);
+		    }
+		  else
+		    p_pnt = p_end ;
+
+		  if ((ok = (p_pnt < p_end)))
+		    orfp.ge = *p_pnt++ ;      /* value checked in prefix_bgp_orf_set() */
+		  if ((ok = (p_pnt < p_end)))
+		    orfp.le = *p_pnt++ ;      /* value checked in prefix_bgp_orf_set() */
+		  if ((ok = (p_pnt < p_end)))
+		    orfp.p.prefixlen = *p_pnt++ ;
+		  orfp.p.family = afi2family (afi);   /* afi checked already  */
+
+		  psize = PSIZE (orfp.p.prefixlen);   /* 0 if not ok          */
+		  if (psize > prefix_blen(&orfp.p))   /* valid for family ?   */
+		    {
+		      ok = 0 ;
+		      psize = prefix_blen(&orfp.p) ;
+		    }
+		  if (psize > (p_end - p_pnt))        /* valid for packet ?   */
+		    {
+		      ok = 0 ;
+		      psize = p_end - p_pnt ;
+		    }
+
+		  if (psize > 0)
+		    memcpy (&orfp.p.u.prefix, p_pnt, psize);
 		  p_pnt += psize;
 
 		  if (BGP_DEBUG (normal, NORMAL))
-		    zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d",
+		    zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
 			       peer->host,
 			       (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"), 
 			       (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
 			       orfp.seq, 
 			       inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
-			       orfp.p.prefixlen, orfp.ge, orfp.le);
+			       orfp.p.prefixlen, orfp.ge, orfp.le,
+			       ok ? "" : " MALFORMED");
+                  
+		  if (ok)
+		    ret = prefix_bgp_orf_set (name, afi, &orfp,
+				   (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
+				   (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
 
-		  ret = prefix_bgp_orf_set (name, afi, &orfp,
-				 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
-				 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
-
-		  if (ret != CMD_SUCCESS)
+		  if (!ok || (ret != CMD_SUCCESS))
 		    {
 		      if (BGP_DEBUG (normal, NORMAL))
-			zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host);
+			zlog_debug ("%s Received misformatted prefixlist ORF."
+			            " Remove All pfxlist", peer->host);
 		      prefix_bgp_orf_remove_all (name);
 		      break;
 		    }
@@ -2237,12 +2258,13 @@
     return 0;
 
   /* Read packet from fd. */
-  nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize);
+  nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
 
   /* If read byte is smaller than zero then error occured. */
   if (nbytes < 0) 
     {
-      if (errno == EAGAIN)
+      /* Transient error should retry */
+      if (nbytes == -2)
 	return -1;
 
       plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index a92ca4e..5c516f0 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -910,19 +910,6 @@
 	}
     }
   
-  /* AS-Pathlimit check */
-  if (ri->attr->pathlimit.ttl && peer_sort (peer) == BGP_PEER_EBGP)
-    /* Our ASN has not yet been pre-pended, that's done in packet_attribute
-     * on output. Hence the test here is for >=.
-     */
-    if (aspath_count_hops (ri->attr->aspath) >= ri->attr->pathlimit.ttl)
-      {
-        if (BGP_DEBUG (filter, FILTER))
-          zlog_info ("%s [Update:SEND] suppressed, AS-Pathlimit TTL %u exceeded",
-                     peer->host, ri->attr->pathlimit.ttl);
-        return 0;
-      }
-  
   /* For modify attribute, copy it to temporary structure. */
   bgp_attr_dup (attr, ri->attr);
   
@@ -1027,39 +1014,6 @@
     }
 #endif /* HAVE_IPV6 */
 
-  /* AS-Pathlimit: Check ASN for private/confed */
-  if (attr->pathlimit.ttl)
-    {
-      /* locally originated update */
-      if (!attr->pathlimit.as)
-        attr->pathlimit.as = peer->local_as;
-      
-      /* if the AS_PATHLIMIT attribute is attached to a prefix by a
-         member of a confederation, then when the prefix is advertised outside
-         of the confederation boundary, then the AS number of the
-         confederation member inside of the AS_PATHLIMIT attribute should be
-         replaced by the confederation's AS number. */
-      if (peer_sort (from) == BGP_PEER_CONFED 
-          && peer_sort (peer) != BGP_PEER_CONFED)
-        attr->pathlimit.as = peer->local_as;
-
-      /* Private ASN should be updated whenever announcement leaves
-       * private space. This is deliberately done after simple confed
-       * based update..
-       */
-      if (attr->pathlimit.as >= BGP_PRIVATE_AS_MIN
-          && attr->pathlimit.as <= BGP_PRIVATE_AS_MAX)
-        {
-          if (peer->local_as < BGP_PRIVATE_AS_MIN 
-              || peer->local_as > BGP_PRIVATE_AS_MAX)
-            attr->pathlimit.as = peer->local_as;
-          /* Ours is private, try using theirs.. */
-          else if (peer->as < BGP_PRIVATE_AS_MIN
-                   || peer->local_as > BGP_PRIVATE_AS_MAX)
-            attr->pathlimit.as = peer->as;
-        }
-    }
-  
   /* If this is EBGP peer and remove-private-AS is set.  */
   if (peer_sort (peer) == BGP_PEER_EBGP
       && peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
@@ -1614,14 +1568,13 @@
     }
   
   bm->process_main_queue->spec.workfunc = &bgp_process_main;
-  bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient;
   bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
-  bm->process_rsclient_queue->spec.del_item_data
-    =  bm->process_main_queue->spec.del_item_data;
-  bm->process_main_queue->spec.max_retries
-    = bm->process_main_queue->spec.max_retries = 0;
-  bm->process_rsclient_queue->spec.hold
-    = bm->process_main_queue->spec.hold = 50;
+  bm->process_main_queue->spec.max_retries = 0;
+  bm->process_main_queue->spec.hold = 50;
+  
+  memcpy (bm->process_rsclient_queue, bm->process_main_queue,
+          sizeof (struct work_queue *));
+  bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient;
 }
 
 void
@@ -3239,14 +3192,6 @@
   attr.med = bgp_static->igpmetric;
   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
   
-  if (bgp_static->ttl)
-    {
-      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
-      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
-      attr.pathlimit.as = 0;
-      attr.pathlimit.ttl = bgp_static->ttl;
-    }
-  
   if (bgp_static->atomic)
     attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
   
@@ -3281,7 +3226,7 @@
   else
     attr_new = bgp_attr_intern (&attr);
   
-  new_attr = *attr_new;
+  bgp_attr_dup(&new_attr, attr_new);
   
   SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
 
@@ -3310,6 +3255,7 @@
 
   bgp_attr_unintern (attr_new);
   attr_new = bgp_attr_intern (&new_attr);
+  bgp_attr_extra_free (&new_attr);
 
   for (ri = rn->info; ri; ri = ri->next)
     if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
@@ -3395,14 +3341,6 @@
   attr.med = bgp_static->igpmetric;
   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
 
-  if (bgp_static->ttl)
-    {
-      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
-      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
-      attr.pathlimit.as = 0;
-      attr.pathlimit.ttl = bgp_static->ttl;
-    }
-
   if (bgp_static->atomic)
     attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
 
@@ -3518,8 +3456,8 @@
 }
 
 static void
-bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,
-			 u_char safi, struct prefix_rd *prd, u_char *tag)
+bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
+			 safi_t safi, struct prefix_rd *prd, u_char *tag)
 {
   struct bgp_node *rn;
   struct bgp_info *new;
@@ -3599,8 +3537,8 @@
 }
 
 static void
-bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,
-			   u_char safi, struct prefix_rd *prd, u_char *tag)
+bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
+			   safi_t safi, struct prefix_rd *prd, u_char *tag)
 {
   struct bgp_node *rn;
   struct bgp_info *ri;
@@ -3626,44 +3564,17 @@
   bgp_unlock_node (rn);
 }
 
-static void
-bgp_pathlimit_update_parents (struct bgp *bgp, struct bgp_node *rn,
-                              int ttl_edge)
-{
-  struct bgp_node *parent = rn;
-  struct bgp_static *sp;
-  
-  /* Existing static changed TTL, search parents and adjust their atomic */
-  while ((parent = parent->parent))
-    if ((sp = parent->info))
-      {
-        int sp_level = (sp->atomic ? 1 : 0);
-        ttl_edge ? sp->atomic++ : sp->atomic--;
-        
-        /* did we change state of parent whether atomic is set or not? */
-        if (sp_level != (sp->atomic ? 1 : 0))
-          {
-            bgp_static_update (bgp, &parent->p, sp,
-                               rn->table->afi, rn->table->safi);
-          }
-      }
-}
-
 /* Configure static BGP network.  When user don't run zebra, static
    route should be installed as valid.  */
 static int
 bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str, 
-                u_int16_t afi, u_char safi, const char *rmap, int backdoor,
-                u_char ttl)
+                afi_t afi, safi_t safi, const char *rmap, int backdoor)
 {
   int ret;
   struct prefix p;
   struct bgp_static *bgp_static;
   struct bgp_node *rn;
   u_char need_update = 0;
-  u_char ttl_change = 0;
-  u_char ttl_edge = (ttl ? 1 : 0);
-  u_char new = 0;
 
   /* Convert IP prefix string to struct prefix. */
   ret = str2prefix (ip_str, &p);
@@ -3692,21 +3603,10 @@
       bgp_static = rn->info;
 
       /* Check previous routes are installed into BGP.  */
-      if (bgp_static->valid)
-        {
-          if (bgp_static->backdoor != backdoor
-              || bgp_static->ttl != ttl)
-            need_update = 1;
-        }
+      if (bgp_static->valid && bgp_static->backdoor != backdoor)
+        need_update = 1;
       
-      /* need to catch TTL set/unset transitions for handling of
-       * ATOMIC_AGGREGATE 
-       */ 
-      if ((bgp_static->ttl ? 1 : 0) != ttl_edge)
-        ttl_change = 1;
-          
       bgp_static->backdoor = backdoor;
-      bgp_static->ttl = ttl;
       
       if (rmap)
 	{
@@ -3733,9 +3633,6 @@
       bgp_static->valid = 0;
       bgp_static->igpmetric = 0;
       bgp_static->igpnexthop.s_addr = 0;
-      bgp_static->ttl = ttl;
-      ttl_change = ttl_edge;
-      new = 1;
       
       if (rmap)
 	{
@@ -3747,39 +3644,6 @@
       rn->info = bgp_static;
     }
 
-  /* ".. sites that choose to advertise the
-   *  AS_PATHLIMIT path attribute SHOULD advertise the ATOMIC_AGGREGATE on
-   *  all less specific covering prefixes as well as the more specific
-   *  prefixes."
-   *
-   * So:
-   * Prefix that has just had pathlimit set/unset:
-   * - Must bump ATOMIC refcount on all parents.
-   *
-   * To catch less specific prefixes:
-   * - Must search children for ones with TTL, bump atomic refcount
-   *   (we dont care if we're deleting a less specific prefix..)
-   */
-  if (ttl_change)
-    {
-      /* Existing static changed TTL, search parents and adjust their atomic */
-      bgp_pathlimit_update_parents (bgp, rn, ttl_edge);
-    }
-  
-  if (new)
-    {
-      struct bgp_node *child;
-      struct bgp_static *sc;
-      
-      /* New static, search children and bump this statics atomic.. */
-      child = bgp_lock_node (rn); /* route_next_until unlocks it.. */
-      while ((child = bgp_route_next_until (child, rn)))
-        {
-          if ((sc = child->info) && sc->ttl)
-            bgp_static->atomic++;
-        }
-    }
-  
   /* If BGP scan is not enabled, we should install this route here.  */
   if (! bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
     {
@@ -3798,7 +3662,7 @@
 /* Configure static BGP network. */
 static int
 bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str,
-		  u_int16_t afi, u_char safi)
+		  afi_t afi, safi_t safi)
 {
   int ret;
   struct prefix p;
@@ -3833,9 +3697,6 @@
 
   bgp_static = rn->info;
   
-  /* decrement atomic in parents, see bgp_static_set */
-  bgp_pathlimit_update_parents (bgp, rn, 0);
-  
   /* Update BGP RIB. */
   if (! bgp_static->backdoor)
     bgp_static_withdraw (bgp, &p, afi, safi);
@@ -4032,23 +3893,10 @@
        "Specify a network to announce via BGP\n"
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
 {
-  u_char ttl = 0;
-  
-  if (argc == 2)
-    VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
-  
   return bgp_static_set (vty, vty->index, argv[0],
-			 AFI_IP, bgp_node_safi (vty), NULL, 0, ttl);
+			 AFI_IP, bgp_node_safi (vty), NULL, 0);
 }
 
-ALIAS (bgp_network,
-       bgp_network_ttl_cmd,
-       "network A.B.C.D/M pathlimit <0-255>",
-       "Specify a network to announce via BGP\n"
-       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 DEFUN (bgp_network_route_map,
        bgp_network_route_map_cmd,
        "network A.B.C.D/M route-map WORD",
@@ -4058,7 +3906,7 @@
        "Name of the route map\n")
 {
   return bgp_static_set (vty, vty->index, argv[0],
-			 AFI_IP, bgp_node_safi (vty), argv[1], 0, 0);
+			 AFI_IP, bgp_node_safi (vty), argv[1], 0);
 }
 
 DEFUN (bgp_network_backdoor,
@@ -4068,24 +3916,10 @@
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
        "Specify a BGP backdoor route\n")
 {
-  u_char ttl = 0;
-  
-  if (argc == 2)
-    VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
-  
   return bgp_static_set (vty, vty->index, argv[0], AFI_IP, SAFI_UNICAST,
-                         NULL, 1, ttl);
+                         NULL, 1);
 }
 
-ALIAS (bgp_network_backdoor,
-       bgp_network_backdoor_ttl_cmd,
-       "network A.B.C.D/M backdoor pathlimit <0-255>",
-       "Specify a network to announce via BGP\n"
-       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
-       "Specify a BGP backdoor route\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 DEFUN (bgp_network_mask,
        bgp_network_mask_cmd,
        "network A.B.C.D mask A.B.C.D",
@@ -4096,10 +3930,6 @@
 {
   int ret;
   char prefix_str[BUFSIZ];
-  u_char ttl = 0;
-  
-  if (argc == 3)
-    VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[2], 1, 255);
   
   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
   if (! ret)
@@ -4109,19 +3939,9 @@
     }
 
   return bgp_static_set (vty, vty->index, prefix_str,
-			 AFI_IP, bgp_node_safi (vty), NULL, 0, ttl);
+			 AFI_IP, bgp_node_safi (vty), NULL, 0);
 }
 
-ALIAS (bgp_network_mask,
-       bgp_network_mask_ttl_cmd,
-       "network A.B.C.D mask A.B.C.D pathlimit <0-255>",
-       "Specify a network to announce via BGP\n"
-       "Network number\n"
-       "Network mask\n"
-       "Network mask\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 DEFUN (bgp_network_mask_route_map,
        bgp_network_mask_route_map_cmd,
        "network A.B.C.D mask A.B.C.D route-map WORD",
@@ -4143,7 +3963,7 @@
     }
 
   return bgp_static_set (vty, vty->index, prefix_str,
-			 AFI_IP, bgp_node_safi (vty), argv[2], 0, 0);
+			 AFI_IP, bgp_node_safi (vty), argv[2], 0);
 }
 
 DEFUN (bgp_network_mask_backdoor,
@@ -4157,11 +3977,7 @@
 {
   int ret;
   char prefix_str[BUFSIZ];
-  u_char ttl = 0;
   
-  if (argc == 3)
-    VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[2], 1, 255);
-
   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
   if (! ret)
     {
@@ -4170,20 +3986,9 @@
     }
 
   return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
-                         NULL, 1, ttl);
+                         NULL, 1);
 }
 
-ALIAS (bgp_network_mask_backdoor,
-       bgp_network_mask_backdoor_ttl_cmd,
-       "network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
-       "Specify a network to announce via BGP\n"
-       "Network number\n"
-       "Network mask\n"
-       "Network mask\n"
-       "Specify a BGP backdoor route\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 DEFUN (bgp_network_mask_natural,
        bgp_network_mask_natural_cmd,
        "network A.B.C.D",
@@ -4192,10 +3997,6 @@
 {
   int ret;
   char prefix_str[BUFSIZ];
-  u_char ttl = 0;
-  
-  if (argc == 2)
-    VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
 
   ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
   if (! ret)
@@ -4205,17 +4006,9 @@
     }
 
   return bgp_static_set (vty, vty->index, prefix_str,
-			 AFI_IP, bgp_node_safi (vty), NULL, 0, ttl);
+			 AFI_IP, bgp_node_safi (vty), NULL, 0);
 }
 
-ALIAS (bgp_network_mask_natural,
-       bgp_network_mask_natural_ttl_cmd,
-       "network A.B.C.D pathlimit <0-255>",
-       "Specify a network to announce via BGP\n"
-       "Network number\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 DEFUN (bgp_network_mask_natural_route_map,
        bgp_network_mask_natural_route_map_cmd,
        "network A.B.C.D route-map WORD",
@@ -4235,7 +4028,7 @@
     }
 
   return bgp_static_set (vty, vty->index, prefix_str,
-			 AFI_IP, bgp_node_safi (vty), argv[1], 0, 0);
+			 AFI_IP, bgp_node_safi (vty), argv[1], 0);
 }
 
 DEFUN (bgp_network_mask_natural_backdoor,
@@ -4247,10 +4040,6 @@
 {
   int ret;
   char prefix_str[BUFSIZ];
-  u_char ttl = 0;
-  
-  if (argc == 2)
-    VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
 
   ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
   if (! ret)
@@ -4260,18 +4049,9 @@
     }
 
   return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
-                         NULL, 1, ttl);
+                         NULL, 1);
 }
 
-ALIAS (bgp_network_mask_natural_backdoor,
-       bgp_network_mask_natural_backdoor_ttl_cmd,
-       "network A.B.C.D backdoor pathlimit (1-255>",
-       "Specify a network to announce via BGP\n"
-       "Network number\n"
-       "Specify a BGP backdoor route\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 DEFUN (no_bgp_network,
        no_bgp_network_cmd,
        "no network A.B.C.D/M",
@@ -4284,15 +4064,6 @@
 }
 
 ALIAS (no_bgp_network,
-       no_bgp_network_ttl_cmd,
-       "no network A.B.C.D/M pathlimit <0-255>",
-       NO_STR
-       "Specify a network to announce via BGP\n"
-       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
-ALIAS (no_bgp_network,
        no_bgp_network_route_map_cmd,
        "no network A.B.C.D/M route-map WORD",
        NO_STR
@@ -4309,16 +4080,6 @@
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
        "Specify a BGP backdoor route\n")
 
-ALIAS (no_bgp_network,
-       no_bgp_network_backdoor_ttl_cmd,
-       "no network A.B.C.D/M backdoor pathlimit <0-255>",
-       NO_STR
-       "Specify a network to announce via BGP\n"
-       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
-       "Specify a BGP backdoor route\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 DEFUN (no_bgp_network_mask,
        no_bgp_network_mask_cmd,
        "no network A.B.C.D mask A.B.C.D",
@@ -4342,17 +4103,6 @@
 			   bgp_node_safi (vty));
 }
 
-ALIAS (no_bgp_network,
-       no_bgp_network_mask_ttl_cmd,
-       "no network A.B.C.D mask A.B.C.D pathlimit <0-255>",
-       NO_STR
-       "Specify a network to announce via BGP\n"
-       "Network number\n"
-       "Network mask\n"
-       "Network mask\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 ALIAS (no_bgp_network_mask,
        no_bgp_network_mask_route_map_cmd,
        "no network A.B.C.D mask A.B.C.D route-map WORD",
@@ -4374,18 +4124,6 @@
        "Network mask\n"
        "Specify a BGP backdoor route\n")
 
-ALIAS (no_bgp_network_mask,
-       no_bgp_network_mask_backdoor_ttl_cmd,
-       "no network A.B.C.D mask A.B.C.D  backdoor pathlimit <0-255>",
-       NO_STR
-       "Specify a network to announce via BGP\n"
-       "Network number\n"
-       "Network mask\n"
-       "Network mask\n"
-       "Specify a BGP backdoor route\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 DEFUN (no_bgp_network_mask_natural,
        no_bgp_network_mask_natural_cmd,
        "no network A.B.C.D",
@@ -4424,25 +4162,6 @@
        "Network number\n"
        "Specify a BGP backdoor route\n")
 
-ALIAS (no_bgp_network_mask_natural,
-       no_bgp_network_mask_natural_ttl_cmd,
-       "no network A.B.C.D pathlimit <0-255>",
-       NO_STR
-       "Specify a network to announce via BGP\n"
-       "Network number\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
-ALIAS (no_bgp_network_mask_natural,
-       no_bgp_network_mask_natural_backdoor_ttl_cmd,
-       "no network A.B.C.D backdoor pathlimit <0-255>",
-       NO_STR
-       "Specify a network to announce via BGP\n"
-       "Network number\n"
-       "Specify a BGP backdoor route\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 #ifdef HAVE_IPV6
 DEFUN (ipv6_bgp_network,
        ipv6_bgp_network_cmd,
@@ -4450,23 +4169,10 @@
        "Specify a network to announce via BGP\n"
        "IPv6 prefix <network>/<length>\n")
 {
-  u_char ttl = 0;
-  
-  if (argc == 2)
-    VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255);
-
   return bgp_static_set (vty, vty->index, argv[0], AFI_IP6, SAFI_UNICAST,
-                         NULL, 0, ttl);
+                         NULL, 0);
 }
 
-ALIAS (ipv6_bgp_network,
-       ipv6_bgp_network_ttl_cmd,
-       "network X:X::X:X/M pathlimit <0-255>",
-       "Specify a network to announce via BGP\n"
-       "IPv6 prefix <network>/<length>\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 DEFUN (ipv6_bgp_network_route_map,
        ipv6_bgp_network_route_map_cmd,
        "network X:X::X:X/M route-map WORD",
@@ -4476,7 +4182,7 @@
        "Name of the route map\n")
 {
   return bgp_static_set (vty, vty->index, argv[0], AFI_IP6,
-			 bgp_node_safi (vty), argv[1], 0, 0);
+			 bgp_node_safi (vty), argv[1], 0);
 }
 
 DEFUN (no_ipv6_bgp_network,
@@ -4498,15 +4204,6 @@
        "Route-map to modify the attributes\n"
        "Name of the route map\n")
 
-ALIAS (no_ipv6_bgp_network,
-       no_ipv6_bgp_network_ttl_cmd,
-       "no network X:X::X:X/M pathlimit <0-255>",
-       NO_STR
-       "Specify a network to announce via BGP\n"
-       "IPv6 prefix <network>/<length>\n"
-       "AS-Path hopcount limit attribute\n"
-       "AS-Pathlimit TTL, in number of AS-Path hops\n")
-
 ALIAS (ipv6_bgp_network,
        old_ipv6_bgp_network_cmd,
        "ipv6 bgp network X:X::X:X/M",
@@ -4524,6 +4221,129 @@
        "Specify a network to announce via BGP\n"
        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
 #endif /* HAVE_IPV6 */
+
+/* stubs for removed AS-Pathlimit commands, kept for config compatibility */
+ALIAS_DEPRECATED (bgp_network,
+       bgp_network_ttl_cmd,
+       "network A.B.C.D/M pathlimit <0-255>",
+       "Specify a network to announce via BGP\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_backdoor,
+       bgp_network_backdoor_ttl_cmd,
+       "network A.B.C.D/M backdoor pathlimit <0-255>",
+       "Specify a network to announce via BGP\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+       "Specify a BGP backdoor route\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_mask,
+       bgp_network_mask_ttl_cmd,
+       "network A.B.C.D mask A.B.C.D pathlimit <0-255>",
+       "Specify a network to announce via BGP\n"
+       "Network number\n"
+       "Network mask\n"
+       "Network mask\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_mask_backdoor,
+       bgp_network_mask_backdoor_ttl_cmd,
+       "network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
+       "Specify a network to announce via BGP\n"
+       "Network number\n"
+       "Network mask\n"
+       "Network mask\n"
+       "Specify a BGP backdoor route\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_mask_natural,
+       bgp_network_mask_natural_ttl_cmd,
+       "network A.B.C.D pathlimit <0-255>",
+       "Specify a network to announce via BGP\n"
+       "Network number\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (bgp_network_mask_natural_backdoor,
+       bgp_network_mask_natural_backdoor_ttl_cmd,
+       "network A.B.C.D backdoor pathlimit (1-255>",
+       "Specify a network to announce via BGP\n"
+       "Network number\n"
+       "Specify a BGP backdoor route\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network,
+       no_bgp_network_ttl_cmd,
+       "no network A.B.C.D/M pathlimit <0-255>",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network,
+       no_bgp_network_backdoor_ttl_cmd,
+       "no network A.B.C.D/M backdoor pathlimit <0-255>",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+       "Specify a BGP backdoor route\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network,
+       no_bgp_network_mask_ttl_cmd,
+       "no network A.B.C.D mask A.B.C.D pathlimit <0-255>",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "Network number\n"
+       "Network mask\n"
+       "Network mask\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network_mask,
+       no_bgp_network_mask_backdoor_ttl_cmd,
+       "no network A.B.C.D mask A.B.C.D  backdoor pathlimit <0-255>",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "Network number\n"
+       "Network mask\n"
+       "Network mask\n"
+       "Specify a BGP backdoor route\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network_mask_natural,
+       no_bgp_network_mask_natural_ttl_cmd,
+       "no network A.B.C.D pathlimit <0-255>",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "Network number\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_bgp_network_mask_natural,
+       no_bgp_network_mask_natural_backdoor_ttl_cmd,
+       "no network A.B.C.D backdoor pathlimit <0-255>",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "Network number\n"
+       "Specify a BGP backdoor route\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+#ifdef HAVE_IPV6
+ALIAS_DEPRECATED (ipv6_bgp_network,
+       ipv6_bgp_network_ttl_cmd,
+       "network X:X::X:X/M pathlimit <0-255>",
+       "Specify a network to announce via BGP\n"
+       "IPv6 prefix <network>/<length>\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+ALIAS_DEPRECATED (no_ipv6_bgp_network,
+       no_ipv6_bgp_network_ttl_cmd,
+       "no network X:X::X:X/M pathlimit <0-255>",
+       NO_STR
+       "Specify a network to announce via BGP\n"
+       "IPv6 prefix <network>/<length>\n"
+       "AS-Path hopcount limit attribute\n"
+       "AS-Pathlimit TTL, in number of AS-Path hops\n")
+#endif /* HAVE_IPV6 */
 
 /* Aggreagete address:
 
@@ -4986,7 +4806,53 @@
 #define AGGREGATE_AS_SET       1
 
 static int
-bgp_aggregate_set (struct vty *vty, const char *prefix_str, 
+bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
+                     afi_t afi, safi_t safi)
+{
+  int ret;
+  struct prefix p;
+  struct bgp_node *rn;
+  struct bgp *bgp;
+  struct bgp_aggregate *aggregate;
+
+  /* Convert string to prefix structure. */
+  ret = str2prefix (prefix_str, &p);
+  if (!ret)
+    {
+      vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+  apply_mask (&p);
+
+  /* Get BGP structure. */
+  bgp = vty->index;
+
+  /* Old configuration check. */
+  rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
+  if (! rn)
+    {
+      vty_out (vty, "%% There is no aggregate-address configuration.%s",
+               VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  aggregate = rn->info;
+  if (aggregate->safi & SAFI_UNICAST)
+    bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
+  if (aggregate->safi & SAFI_MULTICAST)
+    bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
+
+  /* Unlock aggregate address configuration. */
+  rn->info = NULL;
+  bgp_aggregate_free (aggregate);
+  bgp_unlock_node (rn);
+  bgp_unlock_node (rn);
+
+  return CMD_SUCCESS;
+}
+
+static int
+bgp_aggregate_set (struct vty *vty, const char *prefix_str,
                    afi_t afi, safi_t safi,
 		   u_char summary_only, u_char as_set)
 {
@@ -5014,8 +4880,14 @@
   if (rn->info)
     {
       vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
-      bgp_unlock_node (rn);
-      return CMD_WARNING;
+      /* try to remove the old entry */
+      ret = bgp_aggregate_unset (vty, prefix_str, afi, safi);
+      if (ret)
+        {
+          vty_out (vty, "Error deleting aggregate.%s", VTY_NEWLINE);
+	  bgp_unlock_node (rn);
+	  return CMD_WARNING;
+        }
     }
 
   /* Make aggregate address structure. */
@@ -5034,52 +4906,6 @@
   return CMD_SUCCESS;
 }
 
-static int
-bgp_aggregate_unset (struct vty *vty, const char *prefix_str, 
-                     afi_t afi, safi_t safi)
-{
-  int ret;
-  struct prefix p;
-  struct bgp_node *rn;
-  struct bgp *bgp;
-  struct bgp_aggregate *aggregate;
-
-  /* Convert string to prefix structure. */
-  ret = str2prefix (prefix_str, &p);
-  if (!ret)
-    {
-      vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-  apply_mask (&p);
-
-  /* Get BGP structure. */
-  bgp = vty->index;
-
-  /* Old configuration check. */
-  rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
-  if (! rn)
-    {
-      vty_out (vty, "%% There is no aggregate-address configuration.%s",
-	       VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-
-  aggregate = rn->info;
-  if (aggregate->safi & SAFI_UNICAST)
-    bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
-  if (aggregate->safi & SAFI_MULTICAST)
-    bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
-
-  /* Unlock aggregate address configuration. */
-  rn->info = NULL;
-  bgp_aggregate_free (aggregate);
-  bgp_unlock_node (rn);
-  bgp_unlock_node (rn);
-
-  return CMD_SUCCESS;
-}
-
 DEFUN (aggregate_address,
        aggregate_address_cmd,
        "aggregate-address A.B.C.D/M",
@@ -5723,12 +5549,12 @@
 #endif /* HAVE_IPV6 */
 
       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
-	vty_out (vty, "%10d", attr->med);
+	vty_out (vty, "%10u", attr->med);
       else
 	vty_out (vty, "          ");
 
       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
-	vty_out (vty, "%7d", attr->local_pref);
+	vty_out (vty, "%7u", attr->local_pref);
       else
 	vty_out (vty, "       ");
 
@@ -5788,16 +5614,16 @@
 #endif /* HAVE_IPV6 */
 
       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
-	vty_out (vty, "%10d", attr->med);
+	vty_out (vty, "%10u", attr->med);
       else
 	vty_out (vty, "          ");
 
       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
-	vty_out (vty, "%7d", attr->local_pref);
+	vty_out (vty, "%7u", attr->local_pref);
       else
 	vty_out (vty, "       ");
       
-      vty_out (vty, "%7d ", (attr->extra ? attr->extra->weight : 0));
+      vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
       
       /* Print aspath */
       if (attr->aspath)
@@ -5979,6 +5805,9 @@
   char buf1[BUFSIZ];
   struct attr *attr;
   int sockunion_vty_out (struct vty *, union sockunion *);
+#ifdef HAVE_CLOCK_MONOTONIC
+  time_t tbuf;
+#endif
 	
   attr = binfo->attr;
 
@@ -6064,15 +5893,15 @@
       vty_out (vty, "      Origin %s", bgp_origin_long_str[attr->origin]);
 	  
       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
-	vty_out (vty, ", metric %d", attr->med);
+	vty_out (vty, ", metric %u", attr->med);
 	  
       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
-	vty_out (vty, ", localpref %d", attr->local_pref);
+	vty_out (vty, ", localpref %u", attr->local_pref);
       else
-	vty_out (vty, ", localpref %d", bgp->default_local_pref);
+	vty_out (vty, ", localpref %u", bgp->default_local_pref);
 
       if (attr->extra && attr->extra->weight != 0)
-	vty_out (vty, ", weight %d", attr->extra->weight);
+	vty_out (vty, ", weight %u", attr->extra->weight);
 	
       if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
 	vty_out (vty, ", valid");
@@ -6130,22 +5959,16 @@
 	  vty_out (vty, "%s", VTY_NEWLINE);
 	}
       
-      /* 7: AS Pathlimit */
-      if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AS_PATHLIMIT))
-        {
-          
-          vty_out (vty, "      AS-Pathlimit: %u",
-                   attr->pathlimit.ttl);
-          if (attr->pathlimit.as)
-            vty_out (vty, " (%u)", attr->pathlimit.as);
-          vty_out (vty, "%s", VTY_NEWLINE);
-        }
-      
       if (binfo->extra && binfo->extra->damp_info)
 	bgp_damp_info_vty (vty, binfo);
 
       /* Line 7 display Uptime */
-      vty_out (vty, "      Last update: %s", ctime (&binfo->uptime));
+#ifdef HAVE_CLOCK_MONOTONIC
+      tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
+      vty_out (vty, "      Last update: %s", ctime(&tbuf));
+#else
+      vty_out (vty, "      Last update: %s", ctime(&binfo->uptime));
+#endif /* HAVE_CLOCK_MONOTONIC */
     }
   vty_out (vty, "%s", VTY_NEWLINE);
 }  
@@ -6554,7 +6377,10 @@
               if ((rm = bgp_node_match (table, &match)) != NULL)
                 {
                   if (prefix_check && rm->p.prefixlen != match.prefixlen)
-                    continue;
+                    {
+                      bgp_unlock_node (rm);
+                      continue;
+                    }
 
                   for (ri = rm->info; ri; ri = ri->next)
                     {
@@ -6568,6 +6394,8 @@
                       display++;
                       route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN);
                     }
+
+                  bgp_unlock_node (rm);
                 }
             }
         }
@@ -6591,6 +6419,8 @@
                   route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi);
                 }
             }
+
+          bgp_unlock_node (rn);
         }
     }
 
@@ -6663,6 +6493,15 @@
   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL);
 }
 
+ALIAS (show_ip_bgp_ipv4,
+       show_bgp_ipv4_safi_cmd,
+       "show bgp ipv4 (unicast|multicast)",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n")
+
 DEFUN (show_ip_bgp_route,
        show_ip_bgp_route_cmd,
        "show ip bgp A.B.C.D",
@@ -6691,6 +6530,16 @@
   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
 }
 
+ALIAS (show_ip_bgp_ipv4_route,
+       show_bgp_ipv4_safi_route_cmd,
+       "show bgp ipv4 (unicast|multicast) A.B.C.D",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Network in the BGP routing table to display\n")
+
 DEFUN (show_ip_bgp_vpnv4_all_route,
        show_ip_bgp_vpnv4_all_route_cmd,
        "show ip bgp vpnv4 all A.B.C.D",
@@ -6755,6 +6604,16 @@
   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
 }
 
+ALIAS (show_ip_bgp_ipv4_prefix,
+       show_bgp_ipv4_safi_prefix_cmd,
+       "show bgp ipv4 (unicast|multicast) A.B.C.D/M",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+
 DEFUN (show_ip_bgp_vpnv4_all_prefix,
        show_ip_bgp_vpnv4_all_prefix_cmd,
        "show ip bgp vpnv4 all A.B.C.D/M",
@@ -6857,6 +6716,22 @@
        BGP_STR
        "Address family\n")
 
+DEFUN (show_bgp_ipv6_safi,
+       show_bgp_ipv6_safi_cmd,
+       "show bgp ipv6 (unicast|multicast)",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n")
+{
+  if (strncmp (argv[0], "m", 1) == 0)
+    return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal,
+                     NULL);
+
+  return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal, NULL);
+}
+
 /* old command */
 DEFUN (show_ipv6_bgp,
        show_ipv6_bgp_cmd,
@@ -6887,6 +6762,22 @@
        "Address family\n"
        "Network in the BGP routing table to display\n")
 
+DEFUN (show_bgp_ipv6_safi_route,
+       show_bgp_ipv6_safi_route_cmd,
+       "show bgp ipv6 (unicast|multicast) X:X::X:X",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Network in the BGP routing table to display\n")
+{
+  if (strncmp (argv[0], "m", 1) == 0)
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 0);
+
+  return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 0);
+}
+
 /* old command */
 DEFUN (show_ipv6_bgp_route,
        show_ipv6_bgp_route_cmd,
@@ -6917,6 +6808,22 @@
        "Address family\n"
        "IPv6 prefix <network>/<length>\n")
 
+DEFUN (show_bgp_ipv6_safi_prefix,
+       show_bgp_ipv6_safi_prefix_cmd,
+       "show bgp ipv6 (unicast|multicast) X:X::X:X/M",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
+{
+  if (strncmp (argv[0], "m", 1) == 0)
+    return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 1);
+
+  return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1);
+}
+
 /* old command */
 DEFUN (show_ipv6_bgp_prefix,
        show_ipv6_bgp_prefix_cmd,
@@ -7621,15 +7528,36 @@
 #endif /* HAVE_IPV6 */
 
 static int
-bgp_show_community (struct vty *vty, int argc, const char **argv, int exact,
-                    u_int16_t afi, u_char safi)
+bgp_show_community (struct vty *vty, const char *view_name, int argc,
+		    const char **argv, int exact, afi_t afi, safi_t safi)
 {
   struct community *com;
   struct buffer *b;
+  struct bgp *bgp;
   int i;
   char *str;
   int first = 0;
 
+  /* BGP structure lookup */
+  if (view_name)
+    {
+      bgp = bgp_lookup_by_name (view_name);
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+  else
+    {
+      bgp = bgp_get_default ();
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+
   b = buffer_new (1024);
   for (i = 0; i < argc; i++)
     {
@@ -7657,7 +7585,7 @@
       return CMD_WARNING;
     }
 
-  return bgp_show (vty, NULL, afi, safi,
+  return bgp_show (vty, bgp, afi, safi,
                    (exact ? bgp_show_type_community_exact :
 		            bgp_show_type_community), com);
 }
@@ -7674,7 +7602,7 @@
        "Do not advertise to any peer (well-known community)\n"
        "Do not export to next AS (well-known community)\n")
 {
-  return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST);
 }
 
 ALIAS (show_ip_bgp_community,
@@ -7753,9 +7681,9 @@
        "Do not export to next AS (well-known community)\n")
 {
   if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_MULTICAST);
+    return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_MULTICAST);
  
-  return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST);
 }
 
 ALIAS (show_ip_bgp_ipv4_community,
@@ -7827,6 +7755,177 @@
        "Do not advertise to any peer (well-known community)\n"
        "Do not export to next AS (well-known community)\n")
 
+DEFUN (show_bgp_view_afi_safi_community_all,
+       show_bgp_view_afi_safi_community_all_cmd,
+#ifdef HAVE_IPV6
+       "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community",
+#else
+       "show bgp view WORD ipv4 (unicast|multicast) community",
+#endif
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+#ifdef HAVE_IPV6
+       "Address family\n"
+#endif
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Display routes containing communities\n")
+{
+  int afi;
+  int safi;
+  struct bgp *bgp;
+
+  /* BGP structure lookup. */
+  bgp = bgp_lookup_by_name (argv[0]);
+  if (bgp == NULL)
+    {
+      vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+#ifdef HAVE_IPV6
+  afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
+  safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+#else
+  afi = AFI_IP;
+  safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+#endif
+  return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL);
+}
+
+DEFUN (show_bgp_view_afi_safi_community,
+       show_bgp_view_afi_safi_community_cmd,
+#ifdef HAVE_IPV6
+       "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
+#else
+       "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
+#endif
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+#ifdef HAVE_IPV6
+       "Address family\n"
+#endif
+       "Address family modifier\n"
+       "Address family modifier\n"
+       "Display routes matching the communities\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n")
+{
+  int afi;
+  int safi;
+
+#ifdef HAVE_IPV6
+  afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
+  safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  return bgp_show_community (vty, argv[0], argc-3, &argv[3], 0, afi, safi);
+#else
+  afi = AFI_IP;
+  safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  return bgp_show_community (vty, argv[0], argc-2, &argv[2], 0, afi, safi);
+#endif
+}
+
+ALIAS (show_bgp_view_afi_safi_community,
+       show_bgp_view_afi_safi_community2_cmd,
+#ifdef HAVE_IPV6
+       "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#else
+       "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#endif
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+#ifdef HAVE_IPV6
+       "Address family\n"
+#endif
+       "Address family modifier\n"
+       "Address family modifier\n"
+       "Display routes matching the communities\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_view_afi_safi_community,
+       show_bgp_view_afi_safi_community3_cmd,
+#ifdef HAVE_IPV6
+       "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#else
+       "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#endif
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+#ifdef HAVE_IPV6
+       "Address family\n"
+#endif
+       "Address family modifier\n"
+       "Address family modifier\n"
+       "Display routes matching the communities\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n")
+
+ALIAS (show_bgp_view_afi_safi_community,
+       show_bgp_view_afi_safi_community4_cmd,
+#ifdef HAVE_IPV6
+       "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#else
+       "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
+#endif
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+#ifdef HAVE_IPV6
+       "Address family\n"
+#endif
+       "Address family modifier\n"
+       "Address family modifier\n"
+       "Display routes matching the communities\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n"
+       "community number\n"
+       "Do not send outside local AS (well-known community)\n"
+       "Do not advertise to any peer (well-known community)\n"
+       "Do not export to next AS (well-known community)\n")
+
 DEFUN (show_ip_bgp_community_exact,
        show_ip_bgp_community_exact_cmd,
        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
@@ -7840,7 +7939,7 @@
        "Do not export to next AS (well-known community)\n"
        "Exact match of the communities")
 {
-  return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST);
 }
 
 ALIAS (show_ip_bgp_community_exact,
@@ -7923,9 +8022,9 @@
        "Exact match of the communities")
 {
   if (strncmp (argv[0], "m", 1) == 0)
-    return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_MULTICAST);
+    return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_MULTICAST);
  
-  return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST);
 }
 
 ALIAS (show_ip_bgp_ipv4_community_exact,
@@ -8012,7 +8111,7 @@
        "Do not advertise to any peer (well-known community)\n"
        "Do not export to next AS (well-known community)\n")
 {
-  return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
 }
 
 ALIAS (show_bgp_community,
@@ -8157,7 +8256,7 @@
        "Do not advertise to any peer (well-known community)\n"
        "Do not export to next AS (well-known community)\n")
 {
-  return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
 }
 
 /* old command */
@@ -8235,7 +8334,7 @@
        "Do not export to next AS (well-known community)\n"
        "Exact match of the communities")
 {
-  return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
 }
 
 ALIAS (show_bgp_community_exact,
@@ -8388,7 +8487,7 @@
        "Do not export to next AS (well-known community)\n"
        "Exact match of the communities")
 {
-  return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
 }
 
 /* old command */
@@ -8470,7 +8569,7 @@
        "Do not advertise to any peer (well-known community)\n"
        "Do not export to next AS (well-known community)\n")
 {
-  return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_MULTICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_MULTICAST);
 }
 
 /* old command */
@@ -8550,7 +8649,7 @@
        "Do not export to next AS (well-known community)\n"
        "Exact match of the communities")
 {
-  return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_MULTICAST);
+  return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_MULTICAST);
 }
 
 /* old command */
@@ -8622,7 +8721,7 @@
 
 static int
 bgp_show_community_list (struct vty *vty, const char *com, int exact,
-			 u_int16_t afi, u_char safi)
+			 afi_t afi, safi_t safi)
 {
   struct community_list *list;
 
@@ -9959,6 +10058,56 @@
   return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1);
 }
 
+DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes,
+       show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd,
+#ifdef HAVE_IPV6
+       "show bgp view WORD (ipv4|ipv6) (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)",
+#else
+       "show bgp view WORD ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)",
+#endif
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+#ifdef HAVE_IPV6
+       "Address family\n"
+#endif
+       "Address family modifier\n"
+       "Address family modifier\n"
+       "Detailed information on TCP and BGP neighbor connections\n"
+       "Neighbor to display information about\n"
+       "Neighbor to display information about\n"
+       "Display the advertised routes to neighbor\n"
+       "Display the received routes from neighbor\n")
+{
+  int afi;
+  int safi;
+  int in;
+  struct peer *peer;
+
+#ifdef HAVE_IPV6
+    peer = peer_lookup_in_view (vty, argv[0], argv[3]);
+#else
+    peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+#endif
+
+  if (! peer)
+    return CMD_WARNING;
+
+#ifdef HAVE_IPV6
+  afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
+  safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  in = (strncmp (argv[4], "r", 1) == 0) ? 1 : 0;
+#else
+  afi = AFI_IP;
+  safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  in = (strncmp (argv[3], "r", 1) == 0) ? 1 : 0;
+#endif
+
+  return peer_adj_routes (vty, peer, afi, safi, in);
+}
+
 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
        show_ip_bgp_neighbor_received_prefix_filter_cmd,
        "show ip bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
@@ -10366,6 +10515,65 @@
        "Information about Route Server Client\n"
        NEIGHBOR_ADDR_STR)
 
+DEFUN (show_bgp_view_ipv4_safi_rsclient,
+       show_bgp_view_ipv4_safi_rsclient_cmd,
+       "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR)
+{
+  struct bgp_table *table;
+  struct peer *peer;
+  safi_t safi;
+
+  if (argc == 3) {
+    peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+    safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  } else {
+    peer = peer_lookup_in_view (vty, NULL, argv[1]);
+    safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  }
+
+  if (! peer)
+    return CMD_WARNING;
+
+  if (! peer->afc[AFI_IP][safi])
+    {
+      vty_out (vty, "%% Activate the neighbor for the address family first%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi],
+              PEER_FLAG_RSERVER_CLIENT))
+    {
+      vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  table = peer->rib[AFI_IP][safi];
+
+  return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal, NULL);
+}
+
+ALIAS (show_bgp_view_ipv4_safi_rsclient,
+       show_bgp_ipv4_safi_rsclient_cmd,
+       "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR)
+
 DEFUN (show_ip_bgp_view_rsclient_route,
        show_ip_bgp_view_rsclient_route_cmd,
        "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
@@ -10439,6 +10647,87 @@
        NEIGHBOR_ADDR_STR
        "Network in the BGP routing table to display\n")
 
+DEFUN (show_bgp_view_ipv4_safi_rsclient_route,
+       show_bgp_view_ipv4_safi_rsclient_route_cmd,
+       "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR
+       "Network in the BGP routing table to display\n")
+{
+  struct bgp *bgp;
+  struct peer *peer;
+  safi_t safi;
+
+  /* BGP structure lookup. */
+  if (argc == 4)
+    {
+      bgp = bgp_lookup_by_name (argv[0]);
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+  else
+    {
+      bgp = bgp_get_default ();
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+
+  if (argc == 4) {
+    peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+    safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  } else {
+    peer = peer_lookup_in_view (vty, NULL, argv[1]);
+    safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  }
+
+  if (! peer)
+    return CMD_WARNING;
+
+  if (! peer->afc[AFI_IP][safi])
+    {
+      vty_out (vty, "%% Activate the neighbor for the address family first%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+}
+
+  if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi],
+              PEER_FLAG_RSERVER_CLIENT))
+    {
+      vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][safi],
+                                  (argc == 4) ? argv[3] : argv[2],
+                                  AFI_IP, safi, NULL, 0);
+}
+
+ALIAS (show_bgp_view_ipv4_safi_rsclient_route,
+       show_bgp_ipv4_safi_rsclient_route_cmd,
+       "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR
+       "Network in the BGP routing table to display\n")
+
 DEFUN (show_ip_bgp_view_rsclient_prefix,
        show_ip_bgp_view_rsclient_prefix_cmd,
        "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M",
@@ -10512,6 +10801,86 @@
        NEIGHBOR_ADDR_STR
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
 
+DEFUN (show_bgp_view_ipv4_safi_rsclient_prefix,
+       show_bgp_view_ipv4_safi_rsclient_prefix_cmd,
+       "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
+{
+  struct bgp *bgp;
+  struct peer *peer;
+  safi_t safi;
+
+  /* BGP structure lookup. */
+  if (argc == 4)
+    {
+      bgp = bgp_lookup_by_name (argv[0]);
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+  else
+    {
+      bgp = bgp_get_default ();
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+
+  if (argc == 4) {
+    peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+    safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  } else {
+    peer = peer_lookup_in_view (vty, NULL, argv[1]);
+    safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  }
+
+  if (! peer)
+    return CMD_WARNING;
+
+  if (! peer->afc[AFI_IP][safi])
+    {
+      vty_out (vty, "%% Activate the neighbor for the address family first%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+}
+
+  if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi],
+              PEER_FLAG_RSERVER_CLIENT))
+{
+      vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+            VTY_NEWLINE);
+    return CMD_WARNING;
+    }
+
+  return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][safi],
+                                  (argc == 4) ? argv[3] : argv[2],
+                                  AFI_IP, safi, NULL, 1);
+}
+
+ALIAS (show_bgp_view_ipv4_safi_rsclient_prefix,
+       show_bgp_ipv4_safi_rsclient_prefix_cmd,
+       "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
 
 #ifdef HAVE_IPV6
 DEFUN (show_bgp_view_neighbor_routes,
@@ -10778,6 +11147,65 @@
        "Information about Route Server Client\n"
        NEIGHBOR_ADDR_STR)
 
+DEFUN (show_bgp_view_ipv6_safi_rsclient,
+       show_bgp_view_ipv6_safi_rsclient_cmd,
+       "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR)
+{
+  struct bgp_table *table;
+  struct peer *peer;
+  safi_t safi;
+
+  if (argc == 3) {
+    peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+    safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  } else {
+    peer = peer_lookup_in_view (vty, NULL, argv[1]);
+    safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  }
+
+  if (! peer)
+    return CMD_WARNING;
+
+  if (! peer->afc[AFI_IP6][safi])
+    {
+      vty_out (vty, "%% Activate the neighbor for the address family first%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][safi],
+              PEER_FLAG_RSERVER_CLIENT))
+    {
+      vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  table = peer->rib[AFI_IP6][safi];
+
+  return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal, NULL);
+}
+
+ALIAS (show_bgp_view_ipv6_safi_rsclient,
+       show_bgp_ipv6_safi_rsclient_cmd,
+       "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR)
+
 DEFUN (show_bgp_view_rsclient_route,
        show_bgp_view_rsclient_route_cmd,
        "show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X",
@@ -10849,6 +11277,87 @@
        NEIGHBOR_ADDR_STR
        "Network in the BGP routing table to display\n")
 
+DEFUN (show_bgp_view_ipv6_safi_rsclient_route,
+       show_bgp_view_ipv6_safi_rsclient_route_cmd,
+       "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR
+       "Network in the BGP routing table to display\n")
+{
+  struct bgp *bgp;
+  struct peer *peer;
+  safi_t safi;
+
+  /* BGP structure lookup. */
+  if (argc == 4)
+    {
+      bgp = bgp_lookup_by_name (argv[0]);
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+  else
+    {
+      bgp = bgp_get_default ();
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+
+  if (argc == 4) {
+    peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+    safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  } else {
+    peer = peer_lookup_in_view (vty, NULL, argv[1]);
+    safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  }
+
+  if (! peer)
+    return CMD_WARNING;
+
+  if (! peer->afc[AFI_IP6][safi])
+    {
+      vty_out (vty, "%% Activate the neighbor for the address family first%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+}
+
+  if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][safi],
+              PEER_FLAG_RSERVER_CLIENT))
+    {
+      vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP6][safi],
+                                  (argc == 4) ? argv[3] : argv[2],
+                                  AFI_IP6, safi, NULL, 0);
+}
+
+ALIAS (show_bgp_view_ipv6_safi_rsclient_route,
+       show_bgp_ipv6_safi_rsclient_route_cmd,
+       "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR
+       "Network in the BGP routing table to display\n")
+
 DEFUN (show_bgp_view_rsclient_prefix,
        show_bgp_view_rsclient_prefix_cmd,
        "show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M",
@@ -10920,6 +11429,87 @@
        NEIGHBOR_ADDR_STR
        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
 
+DEFUN (show_bgp_view_ipv6_safi_rsclient_prefix,
+       show_bgp_view_ipv6_safi_rsclient_prefix_cmd,
+       "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "BGP view name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR
+       "IP prefix <network>/<length>, e.g., 3ffe::/16\n")
+{
+  struct bgp *bgp;
+  struct peer *peer;
+  safi_t safi;
+
+  /* BGP structure lookup. */
+  if (argc == 4)
+    {
+      bgp = bgp_lookup_by_name (argv[0]);
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+  else
+    {
+      bgp = bgp_get_default ();
+      if (bgp == NULL)
+	{
+	  vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+
+  if (argc == 4) {
+    peer = peer_lookup_in_view (vty, argv[0], argv[2]);
+    safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  } else {
+    peer = peer_lookup_in_view (vty, NULL, argv[1]);
+    safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+  }
+
+  if (! peer)
+    return CMD_WARNING;
+
+  if (! peer->afc[AFI_IP6][safi])
+    {
+      vty_out (vty, "%% Activate the neighbor for the address family first%s",
+            VTY_NEWLINE);
+      return CMD_WARNING;
+}
+
+  if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][safi],
+              PEER_FLAG_RSERVER_CLIENT))
+{
+      vty_out (vty, "%% Neighbor is not a Route-Server client%s",
+            VTY_NEWLINE);
+    return CMD_WARNING;
+    }
+
+  return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP6][safi],
+                                  (argc == 4) ? argv[3] : argv[2],
+                                  AFI_IP6, safi, NULL, 1);
+}
+
+ALIAS (show_bgp_view_ipv6_safi_rsclient_prefix,
+       show_bgp_ipv6_safi_rsclient_prefix_cmd,
+       "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Client\n"
+       NEIGHBOR_ADDR_STR
+       "IP prefix <network>/<length>, e.g., 3ffe::/16\n")
+
 #endif /* HAVE_IPV6 */
 
 struct bgp_table *bgp_distance_table;
@@ -11348,41 +11938,49 @@
 
 	  if ((table = rn->info) != NULL)
 	    if ((rm = bgp_node_match (table, &match)) != NULL)
-	      if (! prefix_check || rm->p.prefixlen == match.prefixlen)
-		{
-		  ri = rm->info;
-		  while (ri)
-		    {
-		      if (ri->extra && ri->extra->damp_info)
-			{
-			  ri_temp = ri->next;
-			  bgp_damp_info_free (ri->extra->damp_info, 1);
-			  ri = ri_temp;
-			}
-		      else
-			ri = ri->next;
-		    }
-		}
+              {
+                if (! prefix_check || rm->p.prefixlen == match.prefixlen)
+                  {
+                    ri = rm->info;
+                    while (ri)
+                      {
+                        if (ri->extra && ri->extra->damp_info)
+                          {
+                            ri_temp = ri->next;
+                            bgp_damp_info_free (ri->extra->damp_info, 1);
+                            ri = ri_temp;
+                          }
+                        else
+                          ri = ri->next;
+                      }
+                  }
+
+                bgp_unlock_node (rm);
+              }
         }
     }
   else
     {
       if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL)
-	if (! prefix_check || rn->p.prefixlen == match.prefixlen)
-	  {
-	    ri = rn->info;
-	    while (ri)
-	      {
-		if (ri->extra && ri->extra->damp_info)
-		  {
-		    ri_temp = ri->next;
-		    bgp_damp_info_free (ri->extra->damp_info, 1);
-		    ri = ri_temp;
-		  }
-		else
-		  ri = ri->next;
-	      }
-	  }
+        {
+          if (! prefix_check || rn->p.prefixlen == match.prefixlen)
+            {
+              ri = rn->info;
+              while (ri)
+                {
+                  if (ri->extra && ri->extra->damp_info)
+                    {
+                      ri_temp = ri->next;
+                      bgp_damp_info_free (ri->extra->damp_info, 1);
+                      ri = ri_temp;
+                    }
+                  else
+                    ri = ri->next;
+                }
+            }
+
+          bgp_unlock_node (rn);
+        }
     }
 
   return CMD_SUCCESS;
@@ -11547,8 +12145,6 @@
 	  {
 	    if (bgp_static->backdoor)
 	      vty_out (vty, " backdoor");
-            if (bgp_static->ttl)
-              vty_out (vty, " pathlimit %u", bgp_static->ttl);
           }
 
 	vty_out (vty, "%s", VTY_NEWLINE);
@@ -11637,12 +12233,6 @@
   install_element (BGP_NODE, &bgp_network_backdoor_cmd);
   install_element (BGP_NODE, &bgp_network_mask_backdoor_cmd);
   install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_cmd);
-  install_element (BGP_NODE, &bgp_network_ttl_cmd);
-  install_element (BGP_NODE, &bgp_network_mask_ttl_cmd);
-  install_element (BGP_NODE, &bgp_network_mask_natural_ttl_cmd);
-  install_element (BGP_NODE, &bgp_network_backdoor_ttl_cmd);
-  install_element (BGP_NODE, &bgp_network_mask_backdoor_ttl_cmd);
-  install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
   install_element (BGP_NODE, &no_bgp_network_cmd);
   install_element (BGP_NODE, &no_bgp_network_mask_cmd);
   install_element (BGP_NODE, &no_bgp_network_mask_natural_cmd);
@@ -11652,12 +12242,6 @@
   install_element (BGP_NODE, &no_bgp_network_backdoor_cmd);
   install_element (BGP_NODE, &no_bgp_network_mask_backdoor_cmd);
   install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_cmd);
-  install_element (BGP_NODE, &no_bgp_network_ttl_cmd);
-  install_element (BGP_NODE, &no_bgp_network_mask_ttl_cmd);
-  install_element (BGP_NODE, &no_bgp_network_mask_natural_ttl_cmd);
-  install_element (BGP_NODE, &no_bgp_network_backdoor_ttl_cmd);
-  install_element (BGP_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
-  install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
 
   install_element (BGP_NODE, &aggregate_address_cmd);
   install_element (BGP_NODE, &aggregate_address_mask_cmd);
@@ -11687,23 +12271,13 @@
   install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd);
   install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
   install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
-  install_element (BGP_IPV4_NODE, &bgp_network_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &bgp_network_mask_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &bgp_network_backdoor_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &bgp_network_mask_backdoor_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);  install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
   install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
   install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd);
   install_element (BGP_IPV4_NODE, &no_bgp_network_route_map_cmd);
   install_element (BGP_IPV4_NODE, &no_bgp_network_mask_route_map_cmd);
   install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_route_map_cmd);
-  install_element (BGP_IPV4_NODE, &no_bgp_network_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &no_bgp_network_mask_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &no_bgp_network_backdoor_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
-  install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);  install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
+  
   install_element (BGP_IPV4_NODE, &aggregate_address_cmd);
   install_element (BGP_IPV4_NODE, &aggregate_address_mask_cmd);
   install_element (BGP_IPV4_NODE, &aggregate_address_summary_only_cmd);
@@ -11732,24 +12306,12 @@
   install_element (BGP_IPV4M_NODE, &bgp_network_route_map_cmd);
   install_element (BGP_IPV4M_NODE, &bgp_network_mask_route_map_cmd);
   install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_route_map_cmd);
-  install_element (BGP_IPV4M_NODE, &bgp_network_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &bgp_network_mask_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &bgp_network_backdoor_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &bgp_network_mask_backdoor_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);  install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
   install_element (BGP_IPV4M_NODE, &no_bgp_network_cmd);
   install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_cmd);
   install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd);
   install_element (BGP_IPV4M_NODE, &no_bgp_network_route_map_cmd);
   install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_route_map_cmd);
   install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_route_map_cmd);
-  install_element (BGP_IPV4M_NODE, &no_bgp_network_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &no_bgp_network_backdoor_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
-  install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);  install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
   install_element (BGP_IPV4M_NODE, &aggregate_address_cmd);
   install_element (BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
   install_element (BGP_IPV4M_NODE, &aggregate_address_summary_only_cmd);
@@ -11773,12 +12335,15 @@
 
   install_element (VIEW_NODE, &show_ip_bgp_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_route_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_route_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_prefix_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_prefix_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_view_cmd);
@@ -11804,6 +12369,11 @@
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_afi_safi_community_all_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_afi_safi_community_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_afi_safi_community2_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_afi_safi_community3_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_afi_safi_community4_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_community_exact_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_community2_exact_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_community3_exact_cmd);
@@ -11822,6 +12392,7 @@
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
@@ -11839,20 +12410,28 @@
   install_element (VIEW_NODE, &show_ip_bgp_neighbor_flap_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_neighbor_damp_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_rsclient_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_rsclient_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_route_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_rsclient_prefix_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_prefix_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_view_neighbor_advertised_route_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_view_neighbor_received_routes_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_ipv4_safi_rsclient_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_ipv4_safi_rsclient_route_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_ipv4_safi_rsclient_prefix_cmd);
   
   /* Restricted node: VIEW_NODE - (set of dangerous commands) */
   install_element (RESTRICTED_NODE, &show_ip_bgp_route_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_route_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_prefix_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_prefix_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_view_route_cmd);
@@ -11865,6 +12444,11 @@
   install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community2_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community_all_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community2_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community3_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community4_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_community_exact_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_community2_exact_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_community3_exact_cmd);
@@ -11874,18 +12458,25 @@
   install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_exact_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_exact_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_rsclient_route_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_rsclient_prefix_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_view_rsclient_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_ipv4_safi_rsclient_route_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_ipv4_safi_rsclient_prefix_cmd);
 
   install_element (ENABLE_NODE, &show_ip_bgp_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_route_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_route_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_route_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_route_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_route_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_prefix_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_prefix_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_view_cmd);
@@ -11911,6 +12502,11 @@
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community2_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community3_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community4_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community_all_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community2_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community3_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community4_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_community_exact_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_community2_exact_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_community3_exact_cmd);
@@ -11929,6 +12525,7 @@
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_routes_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_neighbor_routes_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
@@ -11946,13 +12543,19 @@
   install_element (ENABLE_NODE, &show_ip_bgp_neighbor_flap_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_neighbor_damp_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_rsclient_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_rsclient_route_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_route_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_rsclient_prefix_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_prefix_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_view_neighbor_advertised_route_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_view_neighbor_received_routes_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_ipv4_safi_rsclient_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_route_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_ipv4_safi_rsclient_route_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_ipv4_safi_rsclient_prefix_cmd);
 
  /* BGP dampening clear commands */
   install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
@@ -11970,10 +12573,8 @@
   /* New config IPv6 BGP commands.  */
   install_element (BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
   install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
-  install_element (BGP_IPV6_NODE, &ipv6_bgp_network_ttl_cmd);
   install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
   install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_route_map_cmd);
-  install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_ttl_cmd);
 
   install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
   install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_summary_only_cmd);
@@ -11991,10 +12592,13 @@
 
   install_element (VIEW_NODE, &show_bgp_cmd);
   install_element (VIEW_NODE, &show_bgp_ipv6_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_cmd);
   install_element (VIEW_NODE, &show_bgp_route_cmd);
   install_element (VIEW_NODE, &show_bgp_ipv6_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_route_cmd);
   install_element (VIEW_NODE, &show_bgp_prefix_cmd);
   install_element (VIEW_NODE, &show_bgp_ipv6_prefix_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_prefix_cmd);
   install_element (VIEW_NODE, &show_bgp_regexp_cmd);
   install_element (VIEW_NODE, &show_bgp_ipv6_regexp_cmd);
   install_element (VIEW_NODE, &show_bgp_prefix_list_cmd);
@@ -12040,8 +12644,11 @@
   install_element (VIEW_NODE, &show_bgp_neighbor_damp_cmd);
   install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_damp_cmd);
   install_element (VIEW_NODE, &show_bgp_rsclient_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_cmd);
   install_element (VIEW_NODE, &show_bgp_rsclient_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_route_cmd);
   install_element (VIEW_NODE, &show_bgp_rsclient_prefix_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_prefix_cmd);
   install_element (VIEW_NODE, &show_bgp_view_cmd);
   install_element (VIEW_NODE, &show_bgp_view_ipv6_cmd);
   install_element (VIEW_NODE, &show_bgp_view_route_cmd);
@@ -12061,16 +12668,21 @@
   install_element (VIEW_NODE, &show_bgp_view_neighbor_damp_cmd);
   install_element (VIEW_NODE, &show_bgp_view_ipv6_neighbor_damp_cmd); 
   install_element (VIEW_NODE, &show_bgp_view_rsclient_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_ipv6_safi_rsclient_cmd);
   install_element (VIEW_NODE, &show_bgp_view_rsclient_route_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_ipv6_safi_rsclient_route_cmd);
   install_element (VIEW_NODE, &show_bgp_view_rsclient_prefix_cmd);
+  install_element (VIEW_NODE, &show_bgp_view_ipv6_safi_rsclient_prefix_cmd);
   
   /* Restricted:
    * VIEW_NODE - (set of dangerous commands) - (commands dependent on prev) 
    */
   install_element (RESTRICTED_NODE, &show_bgp_route_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_ipv6_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_route_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_prefix_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_ipv6_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_prefix_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_community_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_ipv6_community_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_community2_cmd);
@@ -12088,7 +12700,9 @@
   install_element (RESTRICTED_NODE, &show_bgp_community4_exact_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_ipv6_community4_exact_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_rsclient_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_rsclient_route_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_rsclient_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_rsclient_prefix_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_view_route_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_route_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_view_prefix_cmd);
@@ -12096,14 +12710,19 @@
   install_element (RESTRICTED_NODE, &show_bgp_view_neighbor_received_prefix_filter_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_neighbor_received_prefix_filter_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_view_rsclient_route_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_safi_rsclient_route_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_view_rsclient_prefix_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_safi_rsclient_prefix_cmd);
 
   install_element (ENABLE_NODE, &show_bgp_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_cmd);
   install_element (ENABLE_NODE, &show_bgp_route_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_route_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_route_cmd);
   install_element (ENABLE_NODE, &show_bgp_prefix_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_prefix_cmd);
   install_element (ENABLE_NODE, &show_bgp_regexp_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_regexp_cmd);
   install_element (ENABLE_NODE, &show_bgp_prefix_list_cmd);
@@ -12149,8 +12768,11 @@
   install_element (ENABLE_NODE, &show_bgp_neighbor_damp_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_damp_cmd);
   install_element (ENABLE_NODE, &show_bgp_rsclient_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_cmd);
   install_element (ENABLE_NODE, &show_bgp_rsclient_route_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_route_cmd);
   install_element (ENABLE_NODE, &show_bgp_rsclient_prefix_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_prefix_cmd);
   install_element (ENABLE_NODE, &show_bgp_view_cmd);
   install_element (ENABLE_NODE, &show_bgp_view_ipv6_cmd);
   install_element (ENABLE_NODE, &show_bgp_view_route_cmd);
@@ -12170,8 +12792,11 @@
   install_element (ENABLE_NODE, &show_bgp_view_neighbor_damp_cmd);
   install_element (ENABLE_NODE, &show_bgp_view_ipv6_neighbor_damp_cmd);
   install_element (ENABLE_NODE, &show_bgp_view_rsclient_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_ipv6_safi_rsclient_cmd);
   install_element (ENABLE_NODE, &show_bgp_view_rsclient_route_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_ipv6_safi_rsclient_route_cmd);
   install_element (ENABLE_NODE, &show_bgp_view_rsclient_prefix_cmd);
+  install_element (ENABLE_NODE, &show_bgp_view_ipv6_safi_rsclient_prefix_cmd);
   
   /* Statistics */
   install_element (ENABLE_NODE, &show_bgp_statistics_cmd);
@@ -12292,6 +12917,54 @@
   install_element (BGP_IPV4_NODE, &bgp_damp_set3_cmd);
   install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
   install_element (BGP_IPV4_NODE, &bgp_damp_unset2_cmd);
+  
+  /* Deprecated AS-Pathlimit commands */
+  install_element (BGP_NODE, &bgp_network_ttl_cmd);
+  install_element (BGP_NODE, &bgp_network_mask_ttl_cmd);
+  install_element (BGP_NODE, &bgp_network_mask_natural_ttl_cmd);
+  install_element (BGP_NODE, &bgp_network_backdoor_ttl_cmd);
+  install_element (BGP_NODE, &bgp_network_mask_backdoor_ttl_cmd);
+  install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
+  
+  install_element (BGP_NODE, &no_bgp_network_ttl_cmd);
+  install_element (BGP_NODE, &no_bgp_network_mask_ttl_cmd);
+  install_element (BGP_NODE, &no_bgp_network_mask_natural_ttl_cmd);
+  install_element (BGP_NODE, &no_bgp_network_backdoor_ttl_cmd);
+  install_element (BGP_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
+  install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
+  
+  install_element (BGP_IPV4_NODE, &bgp_network_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_network_mask_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_network_backdoor_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_network_mask_backdoor_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
+  
+  install_element (BGP_IPV4_NODE, &no_bgp_network_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_network_mask_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_network_backdoor_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
+  install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
+  
+  install_element (BGP_IPV4M_NODE, &bgp_network_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_network_mask_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_network_backdoor_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_network_mask_backdoor_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
+  
+  install_element (BGP_IPV4M_NODE, &no_bgp_network_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &no_bgp_network_backdoor_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
+  install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
+
+#ifdef HAVE_IPV6
+  install_element (BGP_IPV6_NODE, &ipv6_bgp_network_ttl_cmd);
+  install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_ttl_cmd);
+#endif
 }
 
 void
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 5eed348..3e52859 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -116,9 +116,6 @@
 
   /* MPLS label.  */
   u_char tag[3];
-  
-  /* AS-Pathlimit TTL */
-  u_char ttl;
 };
 
 /* Flags which indicate a route is unuseable in some form */
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index aa7dbce..255b25a 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -92,107 +92,15 @@
       origin            :  Done
       tag               :  (This will not be implemented by bgpd)
       weight            :  Done
-      pathlimit		:  Done
 
 o Local extention
 
   set ipv6 next-hop global: Done
   set ipv6 next-hop local : Done
-  set pathlimit ttl       : Done
   set as-path exclude     : Done
-  match pathlimit as     : Done
 
 */ 
 
-/* Compiles either AS or TTL argument. It is amused the VTY code
- * has already range-checked the values to be suitable as TTL or ASN
- */
-static void *
-route_pathlimit_compile (const char *arg)
-{
-  unsigned long tmp;
-  u_int32_t *val;
-  char *endptr = NULL;
-
-  /* TTL or AS value shoud be integer. */
-  if (! all_digit (arg))
-    return NULL;
-  
-  tmp = strtoul (arg, &endptr, 10);
-  if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
-    return NULL;
-   
-  if (!(val = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t))))
-    return NULL;
-  
-  *val = tmp;
-  
-  return val;
-}
-
-static void
-route_pathlimit_free (void *rule)
-{
-  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
-}
-
-static route_map_result_t
-route_match_pathlimit_as (void *rule, struct prefix *prefix, route_map_object_t type,
-      void *object)
-{
-  struct bgp_info *info = object;
-  struct attr *attr = info->attr;
-  uint32_t as = *(uint32_t *)rule;
-  
-  if (type != RMAP_BGP)
-    return RMAP_NOMATCH;
-  
-  if (!attr->pathlimit.as)
-    return RMAP_NOMATCH;
-  
-  if (as == attr->pathlimit.as)
-    return RMAP_MATCH;
-  
-  return RMAP_NOMATCH;
-}
-
-/* 'match pathlimit as' */
-struct route_map_rule_cmd route_match_pathlimit_as_cmd =
-{
-  "pathlimit as",
-  route_match_pathlimit_as,
-  route_pathlimit_compile,
-  route_pathlimit_free
-};
-
-/* Set pathlimit TTL. */
-static route_map_result_t
-route_set_pathlimit_ttl (void *rule, struct prefix *prefix,
-		         route_map_object_t type, void *object)
-{
-  struct bgp_info *info = object;
-  struct attr *attr = info->attr;
-  u_char ttl = *(uint32_t *)rule;
-  
-  if (type == RMAP_BGP)
-    {
-      attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT);
-      attr->pathlimit.ttl = ttl;
-      attr->pathlimit.as = 0;
-    }
-
-  return RMAP_OKAY;
-}
-
-/* Set local preference rule structure. */
-struct route_map_rule_cmd route_set_pathlimit_ttl_cmd = 
-{
-  "pathlimit ttl",
-  route_set_pathlimit_ttl,
-  route_pathlimit_compile,
-  route_pathlimit_free,
-};
-
  /* 'match peer (A.B.C.D|X:X::X:X)' */
 
 /* Compares the peer specified in the 'match peer' clause with the peer
@@ -1485,6 +1393,13 @@
 	  new = community_uniq_sort (merge);
 	  community_free (merge);
 
+	  /* HACK: if the old community is not intern'd,
+	   * we should free it here, or all reference to it may be lost.
+	   * Really need to cleanup attribute caching sometime.
+	   */
+	  if (old->refcnt == 0)
+	    community_free (old);
+
 	  if (new->size == 0)
 	    {
 	      binfo->attr->community = NULL;
@@ -3743,17 +3658,17 @@
        "BGP originator ID attribute\n"
        "IP address of originator\n")
 
-DEFUN (set_pathlimit_ttl,
+DEFUN_DEPRECATED (set_pathlimit_ttl,
        set_pathlimit_ttl_cmd,
        "set pathlimit ttl <1-255>",
        SET_STR
        "BGP AS-Pathlimit attribute\n"
        "Set AS-Path Hop-count TTL\n")
 {
-  return bgp_route_set_add (vty, vty->index, "pathlimit ttl", argv[0]);
+  return CMD_SUCCESS;
 }
 
-DEFUN (no_set_pathlimit_ttl,
+DEFUN_DEPRECATED (no_set_pathlimit_ttl,
        no_set_pathlimit_ttl_cmd,
        "no set pathlimit ttl",
        NO_STR
@@ -3761,10 +3676,7 @@
        "BGP AS-Pathlimit attribute\n"
        "Set AS-Path Hop-count TTL\n")
 {
-  if (argc == 0)
-    return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", NULL);
-  
-  return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", argv[0]);
+  return CMD_SUCCESS;
 }
 
 ALIAS (no_set_pathlimit_ttl,
@@ -3775,17 +3687,17 @@
        "BGP AS-Pathlimit attribute\n"
        "Set AS-Path Hop-count TTL\n")
 
-DEFUN (match_pathlimit_as,
+DEFUN_DEPRECATED (match_pathlimit_as,
        match_pathlimit_as_cmd,
        "match pathlimit as <1-65535>",
        MATCH_STR
        "BGP AS-Pathlimit attribute\n"
        "Match Pathlimit AS number\n")
 {
-  return bgp_route_match_add (vty, vty->index, "pathlimit as", argv[0]);
+  return CMD_SUCCESS;
 }
 
-DEFUN (no_match_pathlimit_as,
+DEFUN_DEPRECATED (no_match_pathlimit_as,
        no_match_pathlimit_as_cmd,
        "no match pathlimit as",
        NO_STR
@@ -3793,10 +3705,7 @@
        "BGP AS-Pathlimit attribute\n"
        "Match Pathlimit AS number\n")
 {
-  if (argc == 0)
-    return bgp_route_match_delete (vty, vty->index, "pathlimit as", NULL);
-  
-  return bgp_route_match_delete (vty, vty->index, "pathlimit as", argv[0]);
+  return CMD_SUCCESS;
 }
 
 ALIAS (no_match_pathlimit_as,
@@ -3959,10 +3868,9 @@
   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
 #endif /* HAVE_IPV6 */
 
-  /* AS-Pathlimit */
-  route_map_install_match (&route_match_pathlimit_as_cmd);
-  route_map_install_set (&route_set_pathlimit_ttl_cmd);
-
+  /* AS-Pathlimit: functionality removed, commands kept for
+   * compatibility.
+   */
   install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
   install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
   install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c
index 91cab60..a249c23 100644
--- a/bgpd/bgp_table.c
+++ b/bgpd/bgp_table.c
@@ -350,7 +350,6 @@
       if (new->p.prefixlen != p->prefixlen)
 	{
 	  match = new;
-	  bgp_lock_node (match);
 	  new = bgp_node_set (table, p);
 	  set_link (match, new);
 	  table->count++;
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 88be52e..e7e7dba 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -213,6 +213,12 @@
     case BGP_ERR_TCPSIG_FAILED:
       str = "Error while applying TCP-Sig to session(s)";
       break;
+    case BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK:
+      str = "ebgp-multihop and ttl-security cannot be configured together";
+      break;
+    case BGP_ERR_NO_IBGP_WITH_TTLHACK:
+      str = "ttl-security only allowed for EBGP peers";
+      break;
     }
   if (str)
     {
@@ -2636,9 +2642,7 @@
   else
     VTY_GET_INTEGER_RANGE ("TTL", ttl, ttl_str, 1, 255);
 
-  peer_ebgp_multihop_set (peer, ttl);
-
-  return CMD_SUCCESS;
+  return bgp_vty_return (vty,  peer_ebgp_multihop_set (peer, ttl));
 }
 
 static int
@@ -2650,9 +2654,7 @@
   if (! peer)
     return CMD_WARNING;
 
-  peer_ebgp_multihop_unset (peer);
-
-  return CMD_SUCCESS;
+  return bgp_vty_return (vty, peer_ebgp_multihop_unset (peer));
 }
 
 /* neighbor ebgp-multihop. */
@@ -3954,6 +3956,42 @@
   return bgp_vty_return (vty, ret);
 }
 
+DEFUN (neighbor_ttl_security,
+       neighbor_ttl_security_cmd,
+       NEIGHBOR_CMD2 "ttl-security hops <1-254>",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Specify the maximum number of hops to the BGP peer\n")
+{
+  struct peer *peer;
+  int gtsm_hops;
+
+  peer = peer_and_group_lookup_vty (vty, argv[0]);
+  if (! peer)
+    return CMD_WARNING;
+    
+  VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[1], 1, 254);
+
+  return bgp_vty_return (vty, peer_ttl_security_hops_set (peer, gtsm_hops));
+}
+
+DEFUN (no_neighbor_ttl_security,
+       no_neighbor_ttl_security_cmd,
+       NO_NEIGHBOR_CMD2 "ttl-security hops <1-254>",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Specify the maximum number of hops to the BGP peer\n")
+{
+  struct peer *peer;
+
+  peer = peer_and_group_lookup_vty (vty, argv[0]);
+  if (! peer)
+    return CMD_WARNING;
+
+  return bgp_vty_return (vty, peer_ttl_security_hops_unset (peer));
+}
+
 /* Address family configuration.  */
 DEFUN (address_family_ipv4,
        address_family_ipv4_cmd,
@@ -6864,6 +6902,16 @@
   return bgp_show_summary_vty (vty, NULL, AFI_IP, SAFI_UNICAST);
 }
 
+ALIAS (show_ip_bgp_ipv4_summary,
+       show_bgp_ipv4_safi_summary_cmd,
+       "show bgp ipv4 (unicast|multicast) summary",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Summary of BGP neighbor status\n")
+
 DEFUN (show_ip_bgp_instance_ipv4_summary,
        show_ip_bgp_instance_ipv4_summary_cmd,
        "show ip bgp view WORD ipv4 (unicast|multicast) summary",
@@ -6883,6 +6931,18 @@
     return bgp_show_summary_vty (vty, argv[0], AFI_IP, SAFI_UNICAST);
 }
 
+ALIAS (show_ip_bgp_instance_ipv4_summary,
+       show_bgp_instance_ipv4_safi_summary_cmd,
+       "show bgp view WORD ipv4 (unicast|multicast) summary",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "View name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Summary of BGP neighbor status\n")
+
 DEFUN (show_ip_bgp_vpnv4_all_summary,
        show_ip_bgp_vpnv4_all_summary_cmd,
        "show ip bgp vpnv4 all summary",
@@ -6961,6 +7021,40 @@
        "Address family\n"
        "Summary of BGP neighbor status\n")
 
+DEFUN (show_bgp_ipv6_safi_summary,
+       show_bgp_ipv6_safi_summary_cmd,
+       "show bgp ipv6 (unicast|multicast) summary",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Summary of BGP neighbor status\n")
+{
+  if (strncmp (argv[0], "m", 1) == 0)
+    return bgp_show_summary_vty (vty, NULL, AFI_IP6, SAFI_MULTICAST);
+
+  return bgp_show_summary_vty (vty, NULL, AFI_IP6, SAFI_UNICAST);
+}
+
+DEFUN (show_bgp_instance_ipv6_safi_summary,
+       show_bgp_instance_ipv6_safi_summary_cmd,
+       "show bgp view WORD ipv6 (unicast|multicast) summary",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "View name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Summary of BGP neighbor status\n")
+{
+  if (strncmp (argv[1], "m", 1) == 0)
+    return bgp_show_summary_vty (vty, argv[0], AFI_IP6, SAFI_MULTICAST);
+
+  return bgp_show_summary_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST);
+}
+
 /* old command */
 DEFUN (show_ipv6_bgp_summary, 
        show_ipv6_bgp_summary_cmd,
@@ -7552,10 +7646,16 @@
 		 p->host, VTY_NEWLINE);
     }
 
-  /* EBGP Multihop */
-  if (peer_sort (p) != BGP_PEER_IBGP && p->ttl > 1)
-    vty_out (vty, "  External BGP neighbor may be up to %d hops away.%s",
-	     p->ttl, VTY_NEWLINE);
+  /* EBGP Multihop and GTSM */
+  if (peer_sort (p) != BGP_PEER_IBGP)
+    {
+      if (p->gtsm_hops > 0)
+	vty_out (vty, "  External BGP neighbor may be up to %d hops away.%s",
+		 p->gtsm_hops, VTY_NEWLINE);
+      else if (p->ttl > 1)
+	vty_out (vty, "  External BGP neighbor may be up to %d hops away.%s",
+		 p->ttl, VTY_NEWLINE);
+    }
 
   /* Local address. */
   if (p->su_local)
@@ -8162,6 +8262,41 @@
   return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP, SAFI_UNICAST);
 }
 
+DEFUN (show_bgp_instance_ipv4_safi_rsclient_summary,
+       show_bgp_instance_ipv4_safi_rsclient_summary_cmd,
+       "show bgp view WORD ipv4 (unicast|multicast) rsclient summary",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "View name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Clients\n"
+       "Summary of all Route Server Clients\n")
+{
+  safi_t safi;
+
+  if (argc == 2) {
+    safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+    return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP, safi);
+  } else {
+    safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+    return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP, safi);
+  }
+}
+
+ALIAS (show_bgp_instance_ipv4_safi_rsclient_summary,
+       show_bgp_ipv4_safi_rsclient_summary_cmd,
+       "show bgp ipv4 (unicast|multicast) rsclient summary",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Clients\n"
+       "Summary of all Route Server Clients\n")
+
 #ifdef HAVE_IPV6
 DEFUN (show_bgp_rsclient_summary,
        show_bgp_rsclient_summary_cmd,
@@ -8206,6 +8341,42 @@
        "Address family\n"
        "Information about Route Server Clients\n"
        "Summary of all Route Server Clients\n")
+
+DEFUN (show_bgp_instance_ipv6_safi_rsclient_summary,
+       show_bgp_instance_ipv6_safi_rsclient_summary_cmd,
+       "show bgp view WORD ipv6 (unicast|multicast) rsclient summary",
+       SHOW_STR
+       BGP_STR
+       "BGP view\n"
+       "View name\n"
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Clients\n"
+       "Summary of all Route Server Clients\n")
+{
+  safi_t safi;
+
+  if (argc == 2) {
+    safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+    return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP6, safi);
+  } else {
+    safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
+    return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP6, safi);
+  }
+}
+
+ALIAS (show_bgp_instance_ipv6_safi_rsclient_summary,
+       show_bgp_ipv6_safi_rsclient_summary_cmd,
+       "show bgp ipv6 (unicast|multicast) rsclient summary",
+       SHOW_STR
+       BGP_STR
+       "Address family\n"
+       "Address Family modifier\n"
+       "Address Family modifier\n"
+       "Information about Route Server Clients\n"
+       "Summary of all Route Server Clients\n")
+
 #endif /* HAVE IPV6 */
 
 /* Redistribute VTY commands.  */
@@ -9752,38 +9923,50 @@
   install_element (VIEW_NODE, &show_ip_bgp_summary_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_instance_summary_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_summary_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_summary_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_summary_cmd);
+  install_element (VIEW_NODE, &show_bgp_instance_ipv4_safi_summary_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_summary_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd);
 #ifdef HAVE_IPV6
   install_element (VIEW_NODE, &show_bgp_summary_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_summary_cmd);
   install_element (VIEW_NODE, &show_bgp_ipv6_summary_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_summary_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_ipv6_summary_cmd);
+  install_element (VIEW_NODE, &show_bgp_instance_ipv6_safi_summary_cmd);
 #endif /* HAVE_IPV6 */
   install_element (RESTRICTED_NODE, &show_ip_bgp_summary_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_instance_summary_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_summary_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_instance_ipv4_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv4_safi_summary_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_summary_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd);
 #ifdef HAVE_IPV6
   install_element (RESTRICTED_NODE, &show_bgp_summary_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_instance_summary_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_ipv6_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_summary_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_safi_summary_cmd);
 #endif /* HAVE_IPV6 */
   install_element (ENABLE_NODE, &show_ip_bgp_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_instance_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_summary_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_instance_ipv4_summary_cmd);
+  install_element (ENABLE_NODE, &show_bgp_instance_ipv4_safi_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd);
 #ifdef HAVE_IPV6
   install_element (ENABLE_NODE, &show_bgp_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_instance_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_summary_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_instance_ipv6_summary_cmd);
+  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_safi_summary_cmd);
 #endif /* HAVE_IPV6 */
 
   /* "show ip bgp neighbors" commands. */
@@ -9847,28 +10030,40 @@
   install_element (VIEW_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
+  install_element (VIEW_NODE, &show_bgp_instance_ipv4_safi_rsclient_summary_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_summary_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_summary_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
   install_element (RESTRICTED_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv4_safi_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_instance_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd);
+  install_element (ENABLE_NODE, &show_bgp_instance_ipv4_safi_rsclient_summary_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_summary_cmd);
 
 #ifdef HAVE_IPV6
   install_element (VIEW_NODE, &show_bgp_rsclient_summary_cmd);
   install_element (VIEW_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_rsclient_summary_cmd);
   install_element (VIEW_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
+  install_element (VIEW_NODE, &show_bgp_instance_ipv6_safi_rsclient_summary_cmd);
+  install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_summary_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_rsclient_summary_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_instance_rsclient_summary_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_safi_rsclient_summary_cmd);
+  install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_ipv6_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_instance_rsclient_summary_cmd);
   install_element (ENABLE_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd);
+  install_element (ENABLE_NODE, &show_bgp_instance_ipv6_safi_rsclient_summary_cmd);
+  install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_summary_cmd);
 #endif /* HAVE_IPV6 */
 
   /* "show ip bgp paths" commands. */
@@ -9909,6 +10104,10 @@
   install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_metric_rmap_cmd);
 #endif /* HAVE_IPV6 */
 
+  /* ttl_security commands */
+  install_element (BGP_NODE, &neighbor_ttl_security_cmd);
+  install_element (BGP_NODE, &no_neighbor_ttl_security_cmd);
+
   /* "show bgp memory" commands. */
   install_element (VIEW_NODE, &show_bgp_memory_cmd);
   install_element (RESTRICTED_NODE, &show_bgp_memory_cmd);
@@ -9952,7 +10151,7 @@
   switch (ret)
     {
     case COMMUNITY_LIST_ERR_CANT_FIND_LIST:
-      vty_out (vty, "%% Can't find communit-list%s", VTY_NEWLINE);
+      vty_out (vty, "%% Can't find community-list%s", VTY_NEWLINE);
       break;
     case COMMUNITY_LIST_ERR_MALFORMED_VAL:
       vty_out (vty, "%% Malformed community-list value%s", VTY_NEWLINE);
@@ -10313,7 +10512,7 @@
   list = community_list_lookup (bgp_clist, argv[0], COMMUNITY_LIST_MASTER);
   if (! list)
     {
-      vty_out (vty, "%% Can't find communit-list%s", VTY_NEWLINE);
+      vty_out (vty, "%% Can't find community-list%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
 
@@ -10663,7 +10862,7 @@
   list = community_list_lookup (bgp_clist, argv[0], EXTCOMMUNITY_LIST_MASTER);
   if (! list)
     {
-      vty_out (vty, "%% Can't find extcommunit-list%s", VTY_NEWLINE);
+      vty_out (vty, "%% Can't find extcommunity-list%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
 
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 882fe37..ee0cc5d 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1379,6 +1379,7 @@
   group->conf->group = group;
   group->conf->as = 0; 
   group->conf->ttl = 1;
+  group->conf->gtsm_hops = 0;
   group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
   UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER);
   UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT);
@@ -1416,6 +1417,9 @@
   /* TTL */
   peer->ttl = conf->ttl;
 
+  /* GTSM hops */
+  peer->gtsm_hops = conf->gtsm_hops;
+
   /* Weight */
   peer->weight = conf->weight;
 
@@ -2663,10 +2667,36 @@
 {
   struct peer_group *group;
   struct listnode *node, *nnode;
+  struct peer *peer1;
 
   if (peer_sort (peer) == BGP_PEER_IBGP)
     return 0;
 
+  /* see comment in peer_ttl_security_hops_set() */
+  if (ttl != MAXTTL)
+    {
+      if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+        {
+          group = peer->group;
+          if (group->conf->gtsm_hops != 0)
+            return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+
+          for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
+            {
+              if (peer_sort (peer1) == BGP_PEER_IBGP)
+                continue;
+
+              if (peer1->gtsm_hops != 0)
+                return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+            }
+        }
+      else
+        {
+          if (peer->gtsm_hops != 0)
+            return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+        }
+    }
+
   peer->ttl = ttl;
 
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
@@ -2700,6 +2730,9 @@
   if (peer_sort (peer) == BGP_PEER_IBGP)
     return 0;
 
+  if (peer->gtsm_hops != 0 && peer->ttl != MAXTTL)
+      return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+
   if (peer_group_active (peer))
     peer->ttl = peer->group->conf->ttl;
   else
@@ -4331,6 +4364,137 @@
   return 0;
 }
 
+/* Set # of hops between us and BGP peer. */
+int
+peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
+{
+  struct peer_group *group;
+  struct listnode *node, *nnode;
+  struct peer *peer1;
+  int ret;
+
+  zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host);
+
+  if (peer_sort (peer) == BGP_PEER_IBGP)
+    return BGP_ERR_NO_IBGP_WITH_TTLHACK;
+
+  /* We cannot configure ttl-security hops when ebgp-multihop is already
+     set.  For non peer-groups, the check is simple.  For peer-groups, it's
+     slightly messy, because we need to check both the peer-group structure
+     and all peer-group members for any trace of ebgp-multihop configuration
+     before actually applying the ttl-security rules.  Cisco really made a
+     mess of this configuration parameter, and OpenBGPD got it right.
+  */
+  
+  if (peer->gtsm_hops == 0) {
+    if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+      {
+        group = peer->group;
+        if (group->conf->ttl != 1)
+          return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+
+        for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
+          {
+            if (peer_sort (peer1) == BGP_PEER_IBGP)
+              continue;
+
+            if (peer1->ttl != 1)
+              return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+          }
+      }
+    else
+      {
+        if (peer->ttl != 1)
+          return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
+      }
+    /* specify MAXTTL on outgoing packets */
+    ret = peer_ebgp_multihop_set (peer, MAXTTL);
+    if (ret != 0)
+      return ret;
+  }
+  
+  peer->gtsm_hops = gtsm_hops;
+
+  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+    {
+      if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
+	sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - gtsm_hops);
+    }
+  else
+    {
+      group = peer->group;
+      for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
+	{
+	  if (peer_sort (peer) == BGP_PEER_IBGP)
+	    continue;
+
+	  peer->gtsm_hops = group->conf->gtsm_hops;
+
+	  /* Change setting of existing peer
+	   *   established then change value (may break connectivity)
+	   *   not established yet (teardown session and restart)
+	   *   no session then do nothing (will get handled by next connection)
+	   */
+	  if (peer->status == Established)
+	    {
+	      if (peer->fd >= 0 && peer->gtsm_hops != 0)
+		sockopt_minttl (peer->su.sa.sa_family, peer->fd,
+				MAXTTL + 1 - peer->gtsm_hops);
+	    }
+	  else if (peer->status < Established)
+	    {
+	      if (BGP_DEBUG (events, EVENTS))
+		zlog_debug ("%s Min-ttl changed", peer->host);
+	      BGP_EVENT_ADD (peer, BGP_Stop);
+	    }
+	}
+    }
+
+  return 0;
+}
+
+int
+peer_ttl_security_hops_unset (struct peer *peer)
+{
+  struct peer_group *group;
+  struct listnode *node, *nnode;
+  struct peer *opeer;
+
+  zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host);
+
+  if (peer_sort (peer) == BGP_PEER_IBGP)
+      return 0;
+
+  /* if a peer-group member, then reset to peer-group default rather than 0 */
+  if (peer_group_active (peer))
+    peer->gtsm_hops = peer->group->conf->gtsm_hops;
+  else
+    peer->gtsm_hops = 0;
+
+  opeer = peer;
+  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+    {
+      if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
+	sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
+    }
+  else
+    {
+      group = peer->group;
+      for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
+	{
+	  if (peer_sort (peer) == BGP_PEER_IBGP)
+	    continue;
+
+	  peer->gtsm_hops = 0;
+	  
+	  if (peer->fd >= 0)
+	    sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
+	}
+    }
+
+  return peer_ebgp_multihop_unset (opeer);
+}
+
 int
 peer_clear (struct peer *peer)
 {
@@ -4635,12 +4799,19 @@
 	  vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
 
       /* EBGP multihop.  */
-      if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1)
+      if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1 &&
+                   !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL))
         if (! peer_group_active (peer) ||
 	    g_peer->ttl != peer->ttl)
 	  vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
 		   VTY_NEWLINE);
 
+     /* ttl-security hops */
+      if (peer_sort (peer) != BGP_PEER_IBGP && peer->gtsm_hops != 0)
+        if (! peer_group_active (peer) || g_peer->gtsm_hops != peer->gtsm_hops)
+          vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,
+                   peer->gtsm_hops, VTY_NEWLINE);
+
       /* disable-connected-check.  */
       if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
 	if (! peer_group_active (peer) ||
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index a5afaed..4da19e7 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -303,6 +303,7 @@
   /* Peer information */
   int fd;			/* File descriptor */
   int ttl;			/* TTL of TCP connection to the peer. */
+  int gtsm_hops;		/* minimum hopcount to peer */
   char *desc;			/* Description of the peer. */
   unsigned short port;          /* Destination port for peer */
   char *host;			/* Printable address of the peer. */
@@ -800,7 +801,9 @@
 #define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP  -27
 #define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS    -28
 #define BGP_ERR_TCPSIG_FAILED			-29
-#define BGP_ERR_MAX                             -30
+#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK	-30
+#define BGP_ERR_NO_IBGP_WITH_TTLHACK		-31
+#define BGP_ERR_MAX				-32
 
 extern struct bgp_master *bm;
 
@@ -953,4 +956,7 @@
 extern int peer_clear (struct peer *);
 extern int peer_clear_soft (struct peer *, afi_t, safi_t, enum bgp_clear_type);
 
+extern int peer_ttl_security_hops_set (struct peer *, int);
+extern int peer_ttl_security_hops_unset (struct peer *);
+
 #endif /* _QUAGGA_BGPD_H */
diff --git a/configure.ac b/configure.ac
index e7c99b0..b981d5b 100755
--- a/configure.ac
+++ b/configure.ac
@@ -8,7 +8,7 @@
 ## $Id$
 AC_PREREQ(2.53)
 
-AC_INIT(Quagga, 0.99.16, [http://bugzilla.quagga.net])
+AC_INIT(Quagga, 0.99.18, [https://bugzilla.quagga.net])
 AC_CONFIG_SRCDIR(lib/zebra.h)
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -219,15 +219,14 @@
 AC_ARG_ENABLE(tcp-zebra,
 [  --enable-tcp-zebra      enable TCP/IP socket connection between zebra and protocol daemon])
 AC_ARG_ENABLE(opaque-lsa,
-[  --enable-opaque-lsa     enable OSPF Opaque-LSA with OSPFAPI support (RFC2370)])
+  AC_HELP_STRING([--disable-opaque-lsa],[do not build OSPF Opaque-LSA with OSPFAPI support (RFC2370)]))
 AC_ARG_ENABLE(ospfapi,
-[  --disable-ospfapi       do not build OSPFAPI to access the OSPF LSA Database, 
-                          (this is the default if --enable-opaque-lsa is not set)])
+[  --disable-ospfapi       do not build OSPFAPI to access the OSPF LSA Database])
 AC_ARG_ENABLE(ospfclient,
 [  --disable-ospfclient    do not build OSPFAPI client for OSPFAPI, 
                           (this is the default if --disable-ospfapi is set)])
 AC_ARG_ENABLE(ospf-te,
-[  --enable-ospf-te        enable Traffic Engineering Extension to OSPF])
+  AC_HELP_STRING([--disable-ospf-te],[disable Traffic Engineering Extension to OSPF]))
 AC_ARG_ENABLE(multipath,
 [  --enable-multipath=ARG  enable multipath function, ARG must be digit])
 AC_ARG_ENABLE(user,
@@ -292,11 +291,11 @@
   AC_DEFINE(HAVE_TCP_ZEBRA,,Use TCP for zebra communication)
 fi
 
-if test "${enable_opaque_lsa}" = "yes"; then
+if test "${enable_opaque_lsa}" != "no"; then
   AC_DEFINE(HAVE_OPAQUE_LSA,,OSPF Opaque LSA)
 fi
 
-if test "${enable_ospf_te}" = "yes"; then
+if test "${enable_ospf_te}" != "no"; then
   AC_DEFINE(HAVE_OPAQUE_LSA,,OSPF Opaque LSA)
   AC_DEFINE(HAVE_OSPF_TE,,OSPF TE)
 fi
@@ -1201,7 +1200,7 @@
 fi
 
 OSPFCLIENT=""
-if test "${enable_opaque_lsa}" = "yes"; then
+if test "${enable_opaque_lsa}" != "no"; then
   if test "${enable_ospfapi}" != "no";then
     AC_DEFINE(SUPPORT_OSPF_API,,OSPFAPI)
 
diff --git a/doc/Makefile.am b/doc/Makefile.am
index c3016b2..cd4d71b 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -43,7 +43,7 @@
 # us to have a generic automatic .pdf rule to build the figure sources
 # because it cant just work from the png's directly it seems - contrary
 # to the documentation...
-quagga.pdf: $(info_TEXINFOS) $(figures_pdf)
+quagga.pdf: $(info_TEXINFOS) $(figures_pdf) $(quagga_TEXINFOS)
 	$(TEXI2PDF) -o "$@" $<
 
 quagga_TEXINFOS = appendix.texi basic.texi bgpd.texi filter.texi install.texi \
diff --git a/doc/bgpd.texi b/doc/bgpd.texi
index 40156b7..e746330 100644
--- a/doc/bgpd.texi
+++ b/doc/bgpd.texi
@@ -149,29 +149,6 @@
 doesn't care about IGP routes when announcing its routes.
 @end deffn
 
-@deffn {BGP} {network @var{A.B.C.D/M} pathlimit <0-255>} {}
-This command configures a route to be originated into BGP, just as with the
-previous command, but additionally sets an AS-Pathlimit TTL to be advertised
-on the route. See draft-ietf-idr-as-pathlimit.
-
-Specifying a TTL of 0 can be used to remove pathlimit from a previously
-configured network statement.
-
-Note that when advertising prefixes with AS-Pathlimit set, all less-specific
-prefixes advertised SHOULD also have the Atomic-Aggregate attribute set.
-Failure to do so increases the risks of accidental routing loops occuring.
-
-This implementation will try to automatically set Atomic-Aggregate as
-appropriate on any less-specific prefixes originated by the same speaker,
-however it will not (and often can not) do so where @b{other} speakers in
-the AS are originating more specifics.
-
-Hence the system administrator must take care to ensure that all
-less-specific prefixes originated carry atomic-aggregate as appropriate, by
-manually configuring speakers originating less-specifics to set
-Atomic-Aggregate on those advertisements!
-@end deffn
-
 @deffn {BGP} {no network @var{A.B.C.D/M}} {}
 @end deffn
 
diff --git a/doc/main.texi b/doc/main.texi
index 9966b35..a575913 100644
--- a/doc/main.texi
+++ b/doc/main.texi
@@ -49,9 +49,9 @@
 @end deffn
 
 @deffn {Interface Command} {ip address @var{address/prefix}} {}
-@deffnx {Interface Command} {ip6 address @var{address/prefix}} {}
+@deffnx {Interface Command} {ipv6 address @var{address/prefix}} {}
 @deffnx {Interface Command} {no ip address @var{address/prefix}} {}
-@deffnx {Interface Command} {no ip6 address @var{address/prefix}} {}
+@deffnx {Interface Command} {no ipv6 address @var{address/prefix}} {}
 Set the IPv4 or IPv6 address/prefix for the interface.
 @end deffn
 
diff --git a/doc/routemap.texi b/doc/routemap.texi
index 9ac001c..db3e72d 100644
--- a/doc/routemap.texi
+++ b/doc/routemap.texi
@@ -155,10 +155,6 @@
 Matches the specified  @var{community_list}
 @end deffn
 
-@deffn {Route-map Command} {match pathlimit as @var{ASN}} {}
-Matches the specified AS-Pathlimit @var{ASN}.
-@end deffn
-
 @node Route Map Set Command
 @section Route Map Set Command
 
@@ -194,16 +190,6 @@
 Set the BGP-4+ link local IPv6 nexthop address.
 @end deffn
 
-@deffn {Route-map Command} {set pathlimit ttl @var{ttl}} {}
-Sets the specified AS-Pathlimit @var{ttl} on the route. This will also cause
-the AS to be set to the local AS. 
-
-Note that the AS-Pathlimit RFC specifies that speakers advertising this
-attribute should set Atomic-aggregate on all less specific routes. Setting
-AS-Pathlimit by route-map does not do this, the user must do so themselves,
-as they wish. 
-@end deffn
-
 @node Route Map Call Command
 @section Route Map Call Command
 
diff --git a/lib/command.c b/lib/command.c
index 478125f..264e0f7 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -3056,7 +3056,7 @@
   if ((level = level_match(argv[0])) == ZLOG_DISABLED)
     return CMD_ERR_NO_MATCH;
 
-  zlog(NULL, level, ((message = argv_concat(argv, argc, 1)) ? message : ""));
+  zlog(NULL, level, "%s", ((message = argv_concat(argv, argc, 1)) ? message : ""));
   if (message)
     XFREE(MTYPE_TMP, message);
   return CMD_SUCCESS;
@@ -3650,6 +3650,8 @@
       install_element (VIEW_NODE, &show_thread_cpu_cmd);
       install_element (ENABLE_NODE, &show_thread_cpu_cmd);
       install_element (RESTRICTED_NODE, &show_thread_cpu_cmd);
+      
+      install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
       install_element (VIEW_NODE, &show_work_queues_cmd);
       install_element (ENABLE_NODE, &show_work_queues_cmd);
     }
diff --git a/lib/distribute.c b/lib/distribute.c
index 242a225..420849d 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -114,16 +114,11 @@
 }
 
 static unsigned int
-distribute_hash_make (struct distribute *dist)
+distribute_hash_make (void *arg)
 {
-  unsigned int i, key;
+  const struct distribute *dist = arg;
 
-  key = 0;
-  if (dist->ifname)
-    for (i = 0; i < strlen (dist->ifname); i++)
-      key += dist->ifname[i];
-
-  return key;
+  return dist->ifname ? string_hash_make (dist->ifname) : 0;
 }
 
 /* If two distribute-list have same value then return 1 else return
@@ -763,7 +758,7 @@
 void
 distribute_list_init (int node)
 {
-  disthash = hash_create ((unsigned int (*) (void *)) distribute_hash_make,
+  disthash = hash_create (distribute_hash_make,
                           (int (*) (const void *, const void *)) distribute_cmp);
 
   if(node==RIP_NODE) {
diff --git a/lib/hash.c b/lib/hash.c
index 672327e..6db79ea 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -101,6 +101,17 @@
   return hash_get (hash, data, NULL);
 }
 
+/* Simple Bernstein hash which is simple and fast for common case */
+unsigned int string_hash_make (const char *str)
+{
+  unsigned int hash = 0;
+
+  while (*str)
+    hash = (hash * 33) ^ (unsigned int) *str++;
+
+  return hash;
+}
+
 /* This function release registered value from specified hash.  When
    release is successfully finished, return the data pointer in the
    hash backet.  */
diff --git a/lib/hash.h b/lib/hash.h
index f4b1c23..4cb772e 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -70,4 +70,6 @@
 extern void hash_clean (struct hash *, void (*) (void *));
 extern void hash_free (struct hash *);
 
+extern unsigned int string_hash_make (const char *);
+
 #endif /* _ZEBRA_HASH_H */
diff --git a/lib/if.c b/lib/if.c
index e310711..86f754b 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -664,7 +664,7 @@
       strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
 	       BUFSIZ - strlen(logbuf));
     }
-  zlog (NULL, LOG_INFO, logbuf);
+  zlog (NULL, LOG_INFO, "%s", logbuf);
 }
 
 /* If two connected address has same prefix return 1. */
@@ -878,3 +878,21 @@
 
   memset (&if_master, 0, sizeof if_master);
 }
+
+void
+if_terminate (void)
+{
+  for (;;)
+    {
+      struct interface *ifp;
+
+      ifp = listnode_head (iflist);
+      if (ifp == NULL)
+	break;
+
+      if_delete (ifp);
+    }
+
+  list_delete (iflist);
+  iflist = NULL;
+}
diff --git a/lib/if.h b/lib/if.h
index c99ab81..841ce51 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -266,6 +266,7 @@
 extern int if_is_multicast (struct interface *);
 extern void if_add_hook (int, int (*)(struct interface *));
 extern void if_init (void);
+extern void if_terminate (void);
 extern void if_dump_all (void);
 extern const char *if_flag_dump(unsigned long);
 
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index ddc62fd..9774be4 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -109,14 +109,9 @@
 static unsigned int
 if_rmap_hash_make (void *data)
 {
-  struct if_rmap *if_rmap = data;
-  unsigned int i, key;
+  const struct if_rmap *if_rmap = data;
 
-  key = 0;
-  for (i = 0; i < strlen (if_rmap->ifname); i++)
-    key += if_rmap->ifname[i];
-
-  return key;
+  return string_hash_make (if_rmap->ifname);
 }
 
 static int
diff --git a/lib/log.c b/lib/log.c
index 0c2f655..df6e13d 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -653,6 +653,9 @@
   if (zl->fp != NULL)
     fclose (zl->fp);
 
+  if (zl->filename != NULL)
+    free (zl->filename);
+
   XFREE (MTYPE_ZLOG, zl);
 }
 
diff --git a/lib/memory.c b/lib/memory.c
index dc09d8a..4090fd9 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -58,7 +58,11 @@
   abort();
 }
 
-/* Memory allocation. */
+/*
+ * Allocate memory of a given size, to be tracked by a given type.
+ * Effects: Returns a pointer to usable memory.  If memory cannot
+ * be allocated, aborts execution.
+ */
 void *
 zmalloc (int type, size_t size)
 {
@@ -74,7 +78,9 @@
   return memory;
 }
 
-/* Memory allocation with num * size with cleared. */
+/*
+ * Allocate memory as in zmalloc, and also clear the memory.
+ */
 void *
 zcalloc (int type, size_t size)
 {
@@ -90,7 +96,13 @@
   return memory;
 }
 
-/* Memory reallocation. */
+/* 
+ * Given a pointer returned by zmalloc or zcalloc, free it and
+ * return a pointer to a new size, basically acting like realloc().
+ * Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
+ * same type.
+ * Effects: Returns a pointer to the new memory, or aborts.
+ */
 void *
 zrealloc (int type, void *ptr, size_t size)
 {
@@ -99,18 +111,34 @@
   memory = realloc (ptr, size);
   if (memory == NULL)
     zerror ("realloc", type, size);
+  if (ptr == NULL)
+    alloc_inc (type);
+
   return memory;
 }
 
-/* Memory free. */
+/*
+ * Free memory allocated by z*alloc or zstrdup.
+ * Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
+ * same type.
+ * Effects: The memory is freed and may no longer be referenced.
+ */
 void
 zfree (int type, void *ptr)
 {
-  alloc_dec (type);
-  free (ptr);
+  if (ptr != NULL)
+    {
+      alloc_dec (type);
+      free (ptr);
+    }
 }
 
-/* String duplication. */
+/*
+ * Duplicate a string, counting memory usage by type.
+ * Effects: The string is duplicated, and the return value must
+ * eventually be passed to zfree with the same type.  The function will
+ * succeed or abort.
+ */
 char *
 zstrdup (int type, const char *str)
 {
diff --git a/lib/memtypes.c b/lib/memtypes.c
index 05d9322..5902067 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -108,6 +108,7 @@
   { MTYPE_BGP_NODE,		"BGP node"			},
   { MTYPE_BGP_ROUTE,		"BGP route"			},
   { MTYPE_BGP_ROUTE_EXTRA,	"BGP ancillary route info"	},
+  { MTYPE_BGP_CONN,		"BGP connected"			},
   { MTYPE_BGP_STATIC,		"BGP static"			},
   { MTYPE_BGP_ADVERTISE_ATTR,	"BGP adv attr"			},
   { MTYPE_BGP_ADVERTISE,	"BGP adv"			},
diff --git a/lib/prefix.c b/lib/prefix.c
index c85e659..61a278c 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -41,7 +41,7 @@
 
 /* Address Famiy Identifier to Address Family converter. */
 int
-afi2family (int afi)
+afi2family (afi_t afi)
 {
   if (afi == AFI_IP)
     return AF_INET;
@@ -52,7 +52,7 @@
   return 0;
 }
 
-int
+afi_t
 family2afi (int family)
 {
   if (family == AF_INET)
@@ -70,15 +70,16 @@
 {
   int offset;
   int shift;
-
-  /* Set both prefix's head pointer. */
-  const u_char *np = (const u_char *)&n->u.prefix;
-  const u_char *pp = (const u_char *)&p->u.prefix;
+  const u_char *np, *pp;
 
   /* If n's prefix is longer than p's one return 0. */
   if (n->prefixlen > p->prefixlen)
     return 0;
 
+  /* Set both prefix's head pointer. */
+  np = (const u_char *)&n->u.prefix;
+  pp = (const u_char *)&p->u.prefix;
+  
   offset = n->prefixlen / PNBBY;
   shift =  n->prefixlen % PNBBY;
 
diff --git a/lib/prefix.h b/lib/prefix.h
index a7598b7..5f1ff05 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -144,8 +144,8 @@
 }
 
 /* Prototypes. */
-extern int afi2family (int);
-extern int family2afi (int);
+extern int afi2family (afi_t);
+extern afi_t family2afi (int);
 
 extern struct prefix *prefix_new (void);
 extern void prefix_free (struct prefix *);
diff --git a/lib/sockunion.c b/lib/sockunion.c
index 6a40f33..a5382a7 100644
--- a/lib/sockunion.c
+++ b/lib/sockunion.c
@@ -527,6 +527,46 @@
   return 0;
 }
 
+int
+sockopt_cork (int sock, int onoff)
+{
+#ifdef TCP_CORK
+  return setsockopt (sock, IPPROTO_TCP, TCP_CORK, &onoff, sizeof(onoff));
+#else
+  return 0;
+#endif
+}
+
+int
+sockopt_minttl (int family, int sock, int minttl)
+{
+#ifdef IP_MINTTL
+  if (family == AF_INET)
+    {
+      int ret = setsockopt (sock, IPPROTO_IP, IP_MINTTL, &minttl, sizeof(minttl));
+      if (ret < 0)
+	  zlog (NULL, LOG_WARNING,
+		"can't set sockopt IP_MINTTL to %d on socket %d: %s",
+		minttl, sock, safe_strerror (errno));
+      return ret;
+    }
+#endif /* IP_MINTTL */
+#ifdef IPV6_MINHOPCNT
+  if (family == AF_INET6)
+    {
+      int ret = setsockopt (sock, IPPROTO_IPV6, IPV6_MINHOPCNT, &minttl, sizeof(minttl));
+      if (ret < 0)
+	  zlog (NULL, LOG_WARNING,
+		"can't set sockopt IPV6_MINHOPCNT to %d on socket %d: %s",
+		minttl, sock, safe_strerror (errno));
+      return ret;
+    }
+#endif
+
+  errno = EOPNOTSUPP;
+  return -1;
+}
+
 /* If same family and same prefix return 1. */
 int
 sockunion_same (union sockunion *su1, union sockunion *su2)
diff --git a/lib/sockunion.h b/lib/sockunion.h
index 96b9a0d..0ee2d63 100644
--- a/lib/sockunion.h
+++ b/lib/sockunion.h
@@ -102,6 +102,8 @@
 extern int sockunion_bind (int sock, union sockunion *, 
                            unsigned short, union sockunion *);
 extern int sockopt_ttl (int family, int sock, int ttl);
+extern int sockopt_minttl (int family, int sock, int minttl);
+extern int sockopt_cork (int sock, int onoff);
 extern int sockunion_socket (union sockunion *su);
 extern const char *inet_sutop (union sockunion *su, char *str);
 extern enum connect_result sockunion_connect (int fd, union sockunion *su, 
diff --git a/lib/table.c b/lib/table.c
index 04df3af..e40e670 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -209,6 +209,10 @@
     {
       if (node->info)
 	matched = node;
+      
+      if (node->p.prefixlen == p->prefixlen)
+        break;
+      
       node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
     }
 
@@ -260,8 +264,8 @@
   while (node && node->p.prefixlen <= p->prefixlen && 
 	 prefix_match (&node->p, p))
     {
-      if (node->p.prefixlen == p->prefixlen && node->info)
-	return route_lock_node (node);
+      if (node->p.prefixlen == p->prefixlen)
+        return node->info ? route_lock_node (node) : NULL;
 
       node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
     }
@@ -283,10 +287,8 @@
 	 prefix_match (&node->p, p))
     {
       if (node->p.prefixlen == p->prefixlen)
-	{
-	  route_lock_node (node);
-	  return node;
-	}
+        return route_lock_node (node);
+      
       match = node;
       node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
     }
diff --git a/lib/thread.c b/lib/thread.c
index e89af54..fd841c2 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -303,7 +303,7 @@
   void *args[3] = {&tmp, vty, &filter};
 
   memset(&tmp, 0, sizeof tmp);
-  tmp.funcname = "TOTAL";
+  tmp.funcname = (char *)"TOTAL";
   tmp.types = filter;
 
 #ifdef HAVE_RUSAGE
@@ -382,6 +382,89 @@
   cpu_record_print(vty, filter);
   return CMD_SUCCESS;
 }
+
+static void
+cpu_record_hash_clear (struct hash_backet *bucket, 
+		      void *args)
+{
+  thread_type *filter = args;
+  struct cpu_thread_history *a = bucket->data;
+  
+  a = bucket->data;
+  if ( !(a->types & *filter) )
+       return;
+  
+  hash_release (cpu_record, bucket->data);
+}
+
+static void
+cpu_record_clear (thread_type filter)
+{
+  thread_type *tmp = &filter;
+  hash_iterate (cpu_record,
+	        (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
+	        tmp);
+}
+
+DEFUN(clear_thread_cpu,
+      clear_thread_cpu_cmd,
+      "clear thread cpu [FILTER]",
+      "Clear stored data\n"
+      "Thread information\n"
+      "Thread CPU usage\n"
+      "Display filter (rwtexb)\n")
+{
+  int i = 0;
+  thread_type filter = (thread_type) -1U;
+
+  if (argc > 0)
+    {
+      filter = 0;
+      while (argv[0][i] != '\0')
+	{
+	  switch ( argv[0][i] )
+	    {
+	    case 'r':
+	    case 'R':
+	      filter |= (1 << THREAD_READ);
+	      break;
+	    case 'w':
+	    case 'W':
+	      filter |= (1 << THREAD_WRITE);
+	      break;
+	    case 't':
+	    case 'T':
+	      filter |= (1 << THREAD_TIMER);
+	      break;
+	    case 'e':
+	    case 'E':
+	      filter |= (1 << THREAD_EVENT);
+	      break;
+	    case 'x':
+	    case 'X':
+	      filter |= (1 << THREAD_EXECUTE);
+	      break;
+	    case 'b':
+	    case 'B':
+	      filter |= (1 << THREAD_BACKGROUND);
+	      break;
+	    default:
+	      break;
+	    }
+	  ++i;
+	}
+      if (filter == 0)
+	{
+	  vty_out(vty, "Invalid filter \"%s\" specified,"
+                  " must contain at least one of 'RWTEXB'%s",
+		  argv[0], VTY_NEWLINE);
+	  return CMD_WARNING;
+	}
+    }
+
+  cpu_record_clear (filter);
+  return CMD_SUCCESS;
+}
 
 /* List allocation and head/tail print out. */
 static void
@@ -903,6 +986,24 @@
   return ready;
 }
 
+/* process a list en masse, e.g. for event thread lists */
+static unsigned int
+thread_process (struct thread_list *list)
+{
+  struct thread *thread;
+  unsigned int ready = 0;
+  
+  for (thread = list->head; thread; thread = thread->next)
+    {
+      thread_list_delete (list, thread);
+      thread->type = THREAD_READY;
+      thread_list_add (&thread->master->ready, thread);
+      ready++;
+    }
+  return ready;
+}
+
+
 /* Fetch next ready thread. */
 struct thread *
 thread_fetch (struct thread_master *m, struct thread *fetch)
@@ -911,41 +1012,48 @@
   fd_set readfd;
   fd_set writefd;
   fd_set exceptfd;
-  struct timeval timer_val;
+  struct timeval timer_val = { .tv_sec = 0, .tv_usec = 0 };
   struct timeval timer_val_bg;
-  struct timeval *timer_wait;
+  struct timeval *timer_wait = &timer_val;
   struct timeval *timer_wait_bg;
 
   while (1)
     {
       int num = 0;
       
-      /* Signals are highest priority */
+      /* Signals pre-empt everything */
       quagga_sigevent_process ();
        
-      /* Normal event are the next highest priority.  */
-      if ((thread = thread_trim_head (&m->event)) != NULL)
-        return thread_run (m, thread, fetch);
-      
-      /* If there are any ready threads from previous scheduler runs,
-       * process top of them.  
+      /* Drain the ready queue of already scheduled jobs, before scheduling
+       * more.
        */
       if ((thread = thread_trim_head (&m->ready)) != NULL)
         return thread_run (m, thread, fetch);
       
+      /* To be fair to all kinds of threads, and avoid starvation, we
+       * need to be careful to consider all thread types for scheduling
+       * in each quanta. I.e. we should not return early from here on.
+       */
+       
+      /* Normal event are the next highest priority.  */
+      thread_process (&m->event);
+      
       /* Structure copy.  */
       readfd = m->readfd;
       writefd = m->writefd;
       exceptfd = m->exceptfd;
       
       /* Calculate select wait timer if nothing else to do */
-      quagga_get_relative (NULL);
-      timer_wait = thread_timer_wait (&m->timer, &timer_val);
-      timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg);
-      
-      if (timer_wait_bg &&
-	  (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
-	timer_wait = timer_wait_bg;
+      if (m->ready.count == 0)
+        {
+          quagga_get_relative (NULL);
+          timer_wait = thread_timer_wait (&m->timer, &timer_val);
+          timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg);
+          
+          if (timer_wait_bg &&
+              (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
+            timer_wait = timer_wait_bg;
+        }
       
       num = select (FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait);
       
diff --git a/lib/thread.h b/lib/thread.h
index b52bc54..978aa6b 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -82,7 +82,7 @@
 struct cpu_thread_history 
 {
   int (*func)(struct thread *);
-  const char *funcname;
+  char *funcname;
   unsigned int total_calls;
   struct time_stats
   {
@@ -197,6 +197,7 @@
 /* Internal libzebra exports */
 extern void thread_getrusage (RUSAGE_T *);
 extern struct cmd_element show_thread_cpu_cmd;
+extern struct cmd_element clear_thread_cpu_cmd;
 
 /* replacements for the system gettimeofday(), clock_gettime() and
  * time() functions, providing support for non-decrementing clock on
diff --git a/lib/vty.c b/lib/vty.c
index e4818eb..bd1dbac 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -250,7 +250,7 @@
 	vty_out (vty, "MOTD file not found%s", VTY_NEWLINE);
     }
   else if (host.motd)
-    vty_out (vty, host.motd);
+    vty_out (vty, "%s", host.motd);
 }
 
 /* Put out prompt and wait input from user. */
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 7c811ed..52b5f41 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -341,7 +341,7 @@
 
 stats:
 
-#define WQ_HYSTERIS_FACTOR 2
+#define WQ_HYSTERESIS_FACTOR 4
 
   /* we yielded, check whether granularity should be reduced */
   if (yielded && (cycles < wq->cycles.granularity))
@@ -349,17 +349,18 @@
       wq->cycles.granularity = ((cycles > 0) ? cycles 
                                              : WORK_QUEUE_MIN_GRANULARITY);
     }
-  
-  if (cycles >= (wq->cycles.granularity))
+  /* otherwise, should granularity increase? */
+  else if (cycles >= (wq->cycles.granularity))
     {
       if (cycles > wq->cycles.best)
         wq->cycles.best = cycles;
       
-      /* along with yielded check, provides hysteris for granularity */
-      if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR * 2))
-        wq->cycles.granularity *= WQ_HYSTERIS_FACTOR; /* quick ramp-up */
-      else if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR))
-        wq->cycles.granularity += WQ_HYSTERIS_FACTOR;
+      /* along with yielded check, provides hysteresis for granularity */
+      if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR
+                                           * WQ_HYSTERESIS_FACTOR))
+        wq->cycles.granularity *= WQ_HYSTERESIS_FACTOR; /* quick ramp-up */
+      else if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR))
+        wq->cycles.granularity += WQ_HYSTERESIS_FACTOR;
     }
 #undef WQ_HYSTERIS_FACTOR
   
diff --git a/lib/zclient.c b/lib/zclient.c
index d3d5322..52a3627 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -339,12 +339,12 @@
   /* Create read thread. */
   zclient_event (ZCLIENT_READ, zclient);
 
-  /* We need interface information. */
-  zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
-
   /* We need router-id information. */
   zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
 
+  /* We need interface information. */
+  zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
+
   /* Flush all redistribute request. */
   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
     if (i != zclient->redist_default && zclient->redist[i])
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 3c999bb..f4b327e 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -199,14 +199,10 @@
   ospf6_lsdb_delete (oa->lsdb);
   ospf6_lsdb_delete (oa->lsdb_self);
 
+  ospf6_spf_table_finish (oa->spf_table);
   ospf6_route_table_delete (oa->spf_table);
   ospf6_route_table_delete (oa->route_table);
 
-#if 0
-  ospf6_spftree_delete (oa->spf_tree);
-  ospf6_route_table_delete (oa->topology_table);
-#endif /*0*/
-
   THREAD_OFF (oa->thread_spf_calculation);
   THREAD_OFF (oa->thread_route_calculation);
 
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 685b147..3efaab4 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -1219,6 +1219,11 @@
   install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
 }
 
+void
+ospf6_asbr_terminate (void)
+{
+  route_map_finish ();
+}
 
 DEFUN (debug_ospf6_asbr,
        debug_ospf6_asbr_cmd,
diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h
index 7166aa3..6deb93e 100644
--- a/ospf6d/ospf6_asbr.h
+++ b/ospf6d/ospf6_asbr.h
@@ -79,6 +79,7 @@
 extern int ospf6_redistribute_config_write (struct vty *vty);
 
 extern void ospf6_asbr_init (void);
+extern void ospf6_asbr_terminate (void);
 
 extern int config_write_ospf6_debug_asbr (struct vty *vty);
 extern void install_element_ospf6_debug_asbr (void);
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index cb34745..236baf1 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -118,6 +118,7 @@
   oi->cost = 1;
   oi->state = OSPF6_INTERFACE_DOWN;
   oi->flag = 0;
+  oi->mtu_ignore = 0;
 
   /* Try to adjust I/O buffer size with IfMtu */
   oi->ifmtu = ifp->mtu6;
@@ -784,6 +785,8 @@
     {
       vty_out (vty, "  Instance ID %d, Interface MTU %d (autodetect: %d)%s",
 	       oi->instance_id, oi->ifmtu, ifp->mtu6, VNL);
+      vty_out (vty, "  MTU mismatch detection: %s%s", oi->mtu_ignore ?
+	       "disabled" : "enabled", VNL);
       inet_ntop (AF_INET, &oi->area->area_id,
                  strbuf, sizeof (strbuf));
       vty_out (vty, "  Area ID %s, Cost %hu%s", strbuf, oi->cost,
@@ -1368,6 +1371,55 @@
   return CMD_SUCCESS;
 }
 
+DEFUN (ipv6_ospf6_mtu_ignore,
+       ipv6_ospf6_mtu_ignore_cmd,
+       "ipv6 ospf6 mtu-ignore",
+       IP6_STR
+       OSPF6_STR
+       "Ignore MTU mismatch on this interface\n"
+       )
+{
+  struct ospf6_interface *oi;
+  struct interface *ifp;
+
+  ifp = (struct interface *) vty->index;
+  assert (ifp);
+
+  oi = (struct ospf6_interface *) ifp->info;
+  if (oi == NULL)
+    oi = ospf6_interface_create (ifp);
+  assert (oi);
+
+  oi->mtu_ignore = 1;
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_ospf6_mtu_ignore,
+       no_ipv6_ospf6_mtu_ignore_cmd,
+       "no ipv6 ospf6 mtu-ignore",
+       NO_STR
+       IP6_STR
+       OSPF6_STR
+       "Ignore MTU mismatch on this interface\n"
+       )
+{
+  struct ospf6_interface *oi;
+  struct interface *ifp;
+
+  ifp = (struct interface *) vty->index;
+  assert (ifp);
+
+  oi = (struct ospf6_interface *) ifp->info;
+  if (oi == NULL)
+    oi = ospf6_interface_create (ifp);
+  assert (oi);
+
+  oi->mtu_ignore = 0;
+
+  return CMD_SUCCESS;
+}
+
 DEFUN (ipv6_ospf6_advertise_prefix_list,
        ipv6_ospf6_advertise_prefix_list_cmd,
        "ipv6 ospf6 advertise prefix-list WORD",
@@ -1495,6 +1547,9 @@
       if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
         vty_out (vty, " ipv6 ospf6 passive%s", VNL);
 
+      if (oi->mtu_ignore)
+        vty_out (vty, " ipv6 ospf6 mtu-ignore%s", VNL);
+
       vty_out (vty, "!%s", VNL);
     }
   return 0;
@@ -1547,6 +1602,9 @@
   install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
   install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
 
+  install_element (INTERFACE_NODE, &ipv6_ospf6_mtu_ignore_cmd);
+  install_element (INTERFACE_NODE, &no_ipv6_ospf6_mtu_ignore_cmd);
+
   install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
   install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
 }
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index 878c29e..cf758c0 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -76,6 +76,9 @@
   /* OSPF6 Interface flag */
   char flag;
 
+  /* MTU mismatch check */
+  u_char mtu_ignore;
+
   /* Decision of DR Election */
   u_int32_t drouter;
   u_int32_t bdrouter;
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 05b11ba..9bc603b 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -1177,6 +1177,8 @@
             }
           ospf6_route_remove (route, oa->route_table);
         }
+      if (route)
+	ospf6_route_unlock (route);
     }
 
   if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c
index c1db374..588b946 100644
--- a/ospf6d/ospf6_lsa.c
+++ b/ospf6d/ospf6_lsa.c
@@ -712,6 +712,11 @@
   ospf6_install_lsa_handler (&unknown_handler);
 }
 
+void
+ospf6_lsa_terminate (void)
+{
+  vector_free (ospf6_lsa_handler_vector);
+}
 
 static char *
 ospf6_lsa_handler_name (struct ospf6_lsa_handler *h)
diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h
index fb0f27c..c1093ca 100644
--- a/ospf6d/ospf6_lsa.h
+++ b/ospf6d/ospf6_lsa.h
@@ -243,6 +243,7 @@
 extern struct ospf6_lsa_handler *ospf6_get_lsa_handler (u_int16_t type);
 
 extern void ospf6_lsa_init (void);
+extern void ospf6_lsa_terminate (void);
 extern void ospf6_lsa_cmd_init (void);
 
 extern int config_write_ospf6_debug_lsa (struct vty *vty);
diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
index a7a96a1..800fae4 100644
--- a/ospf6d/ospf6_main.c
+++ b/ospf6d/ospf6_main.c
@@ -124,6 +124,35 @@
   exit (status);
 }
 
+static void
+ospf6_exit (int status)
+{
+  extern struct ospf6 *ospf6;
+  extern struct zclient *zclient;
+
+  if (ospf6)
+    ospf6_delete (ospf6);
+
+  ospf6_message_terminate ();
+  ospf6_asbr_terminate ();
+  ospf6_lsa_terminate ();
+
+  if_terminate ();
+  vty_terminate ();
+  cmd_terminate ();
+
+  if (zclient)
+    zclient_free (zclient);
+
+  if (master)
+    thread_master_free (master);
+
+  if (zlog_default)
+    closezlog (zlog_default);
+
+  exit (status);
+}
+
 /* SIGHUP handler. */
 static void 
 sighup (void)
@@ -136,7 +165,7 @@
 sigint (void)
 {
   zlog_notice ("Terminating on signal SIGINT");
-  exit (0);
+  ospf6_exit (0);
 }
 
 /* SIGTERM handler. */
@@ -144,7 +173,7 @@
 sigterm (void)
 {
   zlog_notice ("Terminating on signal SIGTERM");
-  exit (0);
+  ospf6_exit (0);
 }
 
 /* SIGUSR1 handler. */
@@ -308,7 +337,7 @@
   zlog_warn ("Thread failed");
 
   /* Not reached. */
-  exit (0);
+  ospf6_exit (0);
 }
 
 
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index 790fc0a..51933b7 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -832,7 +832,7 @@
     ((caddr_t) oh + sizeof (struct ospf6_header));
 
   /* Interface MTU check */
-  if (ntohs (dbdesc->ifmtu) != oi->ifmtu)
+  if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu)
     {
       if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
         zlog_debug ("I/F MTU mismatch");
@@ -1168,6 +1168,24 @@
   return iobuflen;
 }
 
+void
+ospf6_message_terminate (void)
+{
+  if (recvbuf)
+    {
+      XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
+      recvbuf = NULL;
+    }
+
+  if (sendbuf)
+    {
+      XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
+      sendbuf = NULL;
+    }
+
+  iobuflen = 0;
+}
+
 int
 ospf6_receive (struct thread *thread)
 {
diff --git a/ospf6d/ospf6_message.h b/ospf6d/ospf6_message.h
index ebb6308..c72f0af 100644
--- a/ospf6d/ospf6_message.h
+++ b/ospf6d/ospf6_message.h
@@ -123,6 +123,7 @@
 extern void ospf6_lsack_print (struct ospf6_header *);
 
 extern int ospf6_iobuf_size (unsigned int size);
+extern void ospf6_message_terminate (void);
 extern int ospf6_receive (struct thread *thread);
 
 extern int ospf6_hello_send (struct thread *thread);
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index 1e1f4fb..398acfa 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -690,6 +690,8 @@
   struct route_node *rnode;
   struct ospf6_route *next;
 
+  ospf6_route_unlock (route);
+
   rnode = route->rnode;
   route_lock_node (rnode);
   rnode = route_next (rnode);
@@ -701,7 +703,6 @@
 
   assert (rnode->info);
   next = (struct ospf6_route *) rnode->info;
-  ospf6_route_unlock (route);
   ospf6_route_lock (next);
   return next;
 }
@@ -1335,13 +1336,14 @@
 
 DEFUN (debug_ospf6_route,
        debug_ospf6_route_cmd,
-       "debug ospf6 route (table|intra-area|inter-area)",
+       "debug ospf6 route (table|intra-area|inter-area|memory)",
        DEBUG_STR
        OSPF6_STR
        "Debug route table calculation\n"
        "Debug detail\n"
        "Debug intra-area route calculation\n"
        "Debug inter-area route calculation\n"
+       "Debug route memory use\n"
        )
 {
   unsigned char level = 0;
@@ -1352,18 +1354,21 @@
     level = OSPF6_DEBUG_ROUTE_INTRA;
   else if (! strncmp (argv[0], "inter", 5))
     level = OSPF6_DEBUG_ROUTE_INTER;
+  else if (! strncmp (argv[0], "memor", 5))
+    level = OSPF6_DEBUG_ROUTE_MEMORY;
   OSPF6_DEBUG_ROUTE_ON (level);
   return CMD_SUCCESS;
 }
 
 DEFUN (no_debug_ospf6_route,
        no_debug_ospf6_route_cmd,
-       "no debug ospf6 route (table|intra-area|inter-area)",
+       "no debug ospf6 route (table|intra-area|inter-area|memory)",
        NO_STR
        DEBUG_STR
        OSPF6_STR
        "Debug route table calculation\n"
-       "Debug intra-area route calculation\n")
+       "Debug intra-area route calculation\n"
+       "Debug route memory use\n")
 {
   unsigned char level = 0;
 
@@ -1373,6 +1378,8 @@
     level = OSPF6_DEBUG_ROUTE_INTRA;
   else if (! strncmp (argv[0], "inter", 5))
     level = OSPF6_DEBUG_ROUTE_INTER;
+  else if (! strncmp (argv[0], "memor", 5))
+    level = OSPF6_DEBUG_ROUTE_MEMORY;
   OSPF6_DEBUG_ROUTE_OFF (level);
   return CMD_SUCCESS;
 }
diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c
index bfb6df2..cb54961 100644
--- a/ospf6d/ospf6_spf.c
+++ b/ospf6d/ospf6_spf.c
@@ -50,7 +50,9 @@
   struct ospf6_vertex *vb = (struct ospf6_vertex *) b;
 
   /* ascending order */
-  return (va->cost - vb->cost);
+  if (va->cost != vb->cost)
+    return (va->cost - vb->cost);
+  return (va->hops - vb->hops);
 }
 
 static int
@@ -320,22 +322,8 @@
         }
 
       prev = (struct ospf6_vertex *) route->route_option;
-      if (prev->hops > v->hops)
-        {
-          for (ALL_LIST_ELEMENTS (prev->child_list, node, nnode, w))
-            {
-              assert (w->parent == prev);
-              w->parent = v;
-              listnode_add_sort (v->child_list, w);
-            }
-          listnode_delete (prev->parent->child_list, prev);
-          listnode_add_sort (v->parent->child_list, v);
-
-          ospf6_vertex_delete (prev);
-          route->route_option = v;
-        }
-      else
-        ospf6_vertex_delete (v);
+      assert (prev->hops <= v->hops);
+      ospf6_vertex_delete (v);
 
       return -1;
     }
@@ -404,18 +392,19 @@
   caddr_t lsdesc;
   struct ospf6_lsa *lsa;
 
-  /* initialize */
-  candidate_list = pqueue_create ();
-  candidate_list->cmp = ospf6_vertex_cmp;
-
-  ospf6_spf_table_finish (result_table);
-
   /* Install the calculating router itself as the root of the SPF tree */
   /* construct root vertex */
   lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_ROUTER), htonl (0),
                            router_id, oa->lsdb);
   if (lsa == NULL)
     return;
+
+  /* initialize */
+  candidate_list = pqueue_create ();
+  candidate_list->cmp = ospf6_vertex_cmp;
+
+  ospf6_spf_table_finish (result_table);
+
   root = ospf6_vertex_create (lsa);
   root->area = oa;
   root->cost = 0;
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 8237026..2b65be8 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -51,6 +51,8 @@
 /* global ospf6d variable */
 struct ospf6 *ospf6;
 
+static void ospf6_disable (struct ospf6 *o);
+
 static void
 ospf6_top_lsdb_hook_add (struct ospf6_lsa *lsa)
 {
@@ -143,15 +145,17 @@
   return o;
 }
 
-#if 0
-static void
+void
 ospf6_delete (struct ospf6 *o)
 {
   struct listnode *node, *nnode;
   struct ospf6_area *oa;
 
+  ospf6_disable (ospf6);
+
   for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
     ospf6_area_delete (oa);
+  list_delete (o->area_list);
 
   ospf6_lsdb_delete (o->lsdb);
   ospf6_lsdb_delete (o->lsdb_self);
@@ -164,7 +168,6 @@
 
   XFREE (MTYPE_OSPF6_TOP, o);
 }
-#endif
 
 static void
 ospf6_enable (struct ospf6 *o)
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index ba485f9..4b2d2c3 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -69,6 +69,7 @@
 
 /* prototypes */
 extern void ospf6_top_init (void);
+extern void ospf6_delete (struct ospf6 *o);
 
 extern void ospf6_maxage_remove (struct ospf6 *o);
 
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 0a8ac3e..881771a 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -132,6 +132,9 @@
   struct interface *ifp;
 
   ifp = zebra_interface_state_read (zclient->ibuf);
+  if (ifp == NULL)
+    return 0;
+  
   if (IS_OSPF6_DEBUG_ZEBRA (RECV))
     zlog_debug ("Zebra Interface state change: "
                 "%s index %d flags %llx metric %d mtu %d",
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index 7e32195..7a75194 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -565,8 +565,7 @@
       if (IS_DEBUG_OSPF_EVENT)
 	zlog_debug ("ospf_check_abr_status(): new router flags: %x",new_flags);
       ospf->flags = new_flags;
-      OSPF_TIMER_ON (ospf->t_router_lsa_update,
-		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
+      ospf_router_lsa_update (ospf);
     }
 }
 
@@ -760,7 +759,7 @@
             zlog_debug ("ospf_abr_announce_network_to_area(): "
                        "refreshing summary");
           set_metric (old, cost);
-          lsa = ospf_summary_lsa_refresh (area->ospf, old);
+          lsa = ospf_lsa_refresh (area->ospf, old);
           
           if (!lsa)
             {
@@ -1148,7 +1147,7 @@
       if (old) 
 	{ 
 	  set_metric (old, cost);
-	  lsa = ospf_summary_asbr_lsa_refresh (area->ospf, old);
+	  lsa = ospf_lsa_refresh (area->ospf, old);
 	}
       else
 	lsa = ospf_summary_asbr_lsa_originate (p, cost, area);
diff --git a/ospfd/ospf_api.c b/ospfd/ospf_api.c
index 7738319..fc3b51d 100644
--- a/ospfd/ospf_api.c
+++ b/ospfd/ospf_api.c
@@ -219,7 +219,7 @@
 #else /* ORIGINAL_CODING */
   /* API message common header part. */
   zlog_debug
-    ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%lu)",
+    ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)",
      ospf_api_typename (msg->hdr.msgtype), msg->hdr.msgtype, 
      ntohs (msg->hdr.msglen), (unsigned long) ntohl (msg->hdr.msgseq),
      STREAM_DATA (msg->s), STREAM_SIZE (msg->s));
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c
index 15fd2e5..2a9003b 100644
--- a/ospfd/ospf_apiserver.c
+++ b/ospfd/ospf_apiserver.c
@@ -1831,7 +1831,7 @@
 
 /* Periodically refresh opaque LSAs so that they do not expire in
    other routers. */
-void
+struct ospf_lsa *
 ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa)
 {
   struct ospf_apiserver *apiserv;
@@ -1904,7 +1904,7 @@
     }
 
 out:
-  return;
+  return new;
 }
 
 
diff --git a/ospfd/ospf_apiserver.h b/ospfd/ospf_apiserver.h
index 9a8ae25..b60f56b 100644
--- a/ospfd/ospf_apiserver.h
+++ b/ospfd/ospf_apiserver.h
@@ -180,7 +180,7 @@
 extern void ospf_apiserver_config_write_if (struct vty *vty, struct interface *ifp);
 extern void ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa);
 extern int ospf_ospf_apiserver_lsa_originator (void *arg);
-extern void ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa);
+extern struct ospf_lsa *ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa);
 extern void ospf_apiserver_flush_opaque_lsa (struct ospf_apiserver *apiserv,
 				      u_char lsa_type, u_char opaque_type);
 
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index 6f1b0b0..c39efee 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -264,8 +264,7 @@
 
   /* Transition from/to status ASBR, schedule timer. */
   ospf_spf_calculate_schedule (ospf);
-  OSPF_TIMER_ON (ospf->t_router_lsa_update,
-		 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
+  ospf_router_lsa_update (ospf);
 }
 
 void
diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c
index 5d0cae4..3c19931 100644
--- a/ospfd/ospf_ase.c
+++ b/ospfd/ospf_ase.c
@@ -451,8 +451,8 @@
 
   /* if there is a Intra/Inter area route to the N
      do not install external route */
-  if (rn = route_node_lookup (ospf->new_table,
-			      (struct prefix *) &p))
+  if ((rn = route_node_lookup (ospf->new_table,
+			      (struct prefix *) &p)))
     {
       route_unlock_node(rn);
       if (rn->info == NULL)
@@ -463,8 +463,8 @@
     }
   /* Find a route to the same dest */
   /* If there is no route, create new one. */
-  if (rn = route_node_lookup (ospf->new_external_route,
-			       (struct prefix *) &p))
+  if ((rn = route_node_lookup (ospf->new_external_route,
+			       (struct prefix *) &p)))
       route_unlock_node(rn);
 
   if (!rn || (or = rn->info) == NULL)
@@ -718,7 +718,6 @@
 
   /* We assume that if LSA is deleted from DB
      is is also deleted from this RT */
-
   listnode_add (lst, ospf_lsa_lock (lsa)); /* external_lsas lst */
 }
 
@@ -799,7 +798,8 @@
     }
 
   rn = route_node_lookup (ospf->external_lsas, (struct prefix *) &p);
-  assert (rn && rn->info);
+  assert (rn); 
+  assert (rn->info);
   lsas = rn->info;
   route_unlock_node (rn);
 
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index 41661da..77f2e16 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -135,7 +135,7 @@
       /* Originate a new instance and schedule flooding */
       if (area->router_lsa_self)
 	area->router_lsa_self->data->ls_seqnum = new->data->ls_seqnum;
-      ospf_router_lsa_timer_add (area);
+      ospf_router_lsa_update_area (area);
       return;
     case OSPF_NETWORK_LSA:
 #ifdef HAVE_OPAQUE_LSA
@@ -171,7 +171,7 @@
             if (oi->network_lsa_self)
 	      oi->network_lsa_self->data->ls_seqnum = new->data->ls_seqnum;
             /* Schedule network-LSA origination. */
-            ospf_network_lsa_timer_add (oi);
+            ospf_network_lsa_update (oi);
             return;
           }
       break;
@@ -991,3 +991,33 @@
   ospf_flood_through_as (ospf, NULL, lsa);
   ospf_lsa_maxage (ospf, lsa);
 }
+
+void
+ospf_lsa_flush (struct ospf *ospf, struct ospf_lsa *lsa)
+{
+  lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
+  
+  switch (lsa->data->type)
+    {
+      case OSPF_ROUTER_LSA:
+      case OSPF_NETWORK_LSA:
+      case OSPF_SUMMARY_LSA:
+      case OSPF_ASBR_SUMMARY_LSA:
+      case OSPF_AS_NSSA_LSA:
+#ifdef HAVE_OPAQUE_LSA
+      case OSPF_OPAQUE_LINK_LSA:
+      case OSPF_OPAQUE_AREA_LSA:
+#endif /* HAVE_OPAQUE_LSA */
+        ospf_lsa_flush_area (lsa, lsa->area);
+        break;
+      case OSPF_AS_EXTERNAL_LSA:
+#ifdef HAVE_OPAQUE_LSA
+      case OSPF_OPAQUE_AS_LSA:
+#endif /* HAVE_OPAQUE_LSA */
+        ospf_lsa_flush_as (ospf, lsa);
+        break;
+      default:
+        zlog_info ("%s: Unknown LSA type %u", __func__, lsa->data->type);
+        break;
+    }
+}
diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h
index 5382e8f..1ab11b8 100644
--- a/ospfd/ospf_flood.h
+++ b/ospfd/ospf_flood.h
@@ -66,6 +66,7 @@
 extern void ospf_flood_lsa_as (struct ospf_lsa *);
 extern void ospf_lsa_flush_area (struct ospf_lsa *, struct ospf_area *);
 extern void ospf_lsa_flush_as (struct ospf *, struct ospf_lsa *);
+extern void ospf_lsa_flush (struct ospf *, struct ospf_lsa *);
 extern struct external_info *ospf_external_info_check (struct ospf_lsa *);
 
 extern void ospf_lsdb_init (struct ospf_lsdb *);
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index afe3acf..dc0787d 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -97,7 +97,7 @@
       if (oi->output_cost != newcost)
 	{
 	  oi->output_cost = newcost;
-	  ospf_router_lsa_timer_add (oi->area);
+	  ospf_router_lsa_update_area (oi->area);
 	}
     }
 }
@@ -219,9 +219,6 @@
   ospf_add_to_if (ifp, oi);
   listnode_add (ospf->oiflist, oi);
   
-  /* Clear self-originated network-LSA. */
-  oi->network_lsa_self = NULL;
-
   /* Initialize neighbor list. */
   oi->nbrs = route_table_init ();
 
@@ -301,10 +298,6 @@
   ospf_nbr_delete (oi->nbr_self);
   oi->nbr_self = ospf_nbr_new (oi);
   ospf_nbr_add_self (oi);
-  
-  ospf_lsa_unlock (&oi->network_lsa_self);
-  oi->network_lsa_self = NULL;
-  OSPF_TIMER_OFF (oi->t_network_lsa_self);
 }
 
 void
@@ -335,6 +328,8 @@
   listnode_delete (oi->ospf->oiflist, oi);
   listnode_delete (oi->area->oiflist, oi);
 
+  thread_cancel_event (master, oi);
+
   memset (oi, 0, sizeof (*oi));
   XFREE (MTYPE_OSPF_IF, oi);
 }
@@ -534,6 +529,8 @@
 
   oip->auth_crypt = list_new ();
   
+  oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
+
   return oip;
 }
 
@@ -572,7 +569,8 @@
       !OSPF_IF_PARAM_CONFIGURED (oip, type) &&
       !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&
       !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) &&
-      listcount (oip->auth_crypt) == 0)
+      listcount (oip->auth_crypt) == 0 &&
+      ntohl (oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER)
     {
       ospf_del_if_params (oip);
       rn->info = NULL;
@@ -1121,8 +1119,8 @@
              if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
                zlog_debug ("ospf_vl_up_check: VL cost change,"
                           " scheduling router lsa refresh");
-             if(ospf->backbone)
-               ospf_router_lsa_timer_add (ospf->backbone);
+             if (ospf->backbone)
+               ospf_router_lsa_update_area (ospf->backbone);
              else if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
                zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!");
            }
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index ab0b758..6db8877 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -73,6 +73,9 @@
   
   DECLARE_IF_PARAM (struct list *, auth_crypt);    /* List of Auth cryptographic data. */
   DECLARE_IF_PARAM (int, auth_type);               /* OSPF authentication type */
+  
+  /* Other, non-configuration state */
+  u_int32_t network_lsa_seqnum;		/* Network LSA seqnum */
 };
 
 enum
@@ -167,6 +170,7 @@
 
   /* Configured varables. */
   struct ospf_if_params *params;
+  
   u_int32_t crypt_seqnum;		/* Cryptographic Sequence Number */ 
   u_int32_t output_cost;	        /* Acutual Interface Output Cost */
 
@@ -206,8 +210,6 @@
   struct thread *t_ls_ack;              /* timer */
   struct thread *t_ls_ack_direct;       /* event */
   struct thread *t_ls_upd_event;        /* event */
-  struct thread *t_network_lsa_self;    /* self-originated network-LSA
-                                           reflesh thread. timer */
 #ifdef HAVE_OPAQUE_LSA
   struct thread *t_opaque_lsa_self;     /* Type-9 Opaque-LSAs */
 #endif /* HAVE_OPAQUE_LSA */
diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c
index 1840283..db53882 100644
--- a/ospfd/ospf_ism.c
+++ b/ospfd/ospf_ism.c
@@ -221,8 +221,8 @@
 
   new_state = ospf_ism_state (oi);
 
-  zlog_info ("DR-Election[1st]: Backup %s", inet_ntoa (BDR (oi)));
-  zlog_info ("DR-Election[1st]: DR     %s", inet_ntoa (DR (oi)));
+  zlog_debug ("DR-Election[1st]: Backup %s", inet_ntoa (BDR (oi)));
+  zlog_debug ("DR-Election[1st]: DR     %s", inet_ntoa (DR (oi)));
 
   if (new_state != old_state &&
       !(new_state == ISM_DROther && old_state < ISM_DROther))
@@ -232,8 +232,8 @@
 
       new_state = ospf_ism_state (oi);
 
-      zlog_info ("DR-Election[2nd]: Backup %s", inet_ntoa (BDR (oi)));
-      zlog_info ("DR-Election[2nd]: DR     %s", inet_ntoa (DR (oi)));
+      zlog_debug ("DR-Election[2nd]: Backup %s", inet_ntoa (BDR (oi)));
+      zlog_debug ("DR-Election[2nd]: DR     %s", inet_ntoa (DR (oi)));
     }
 
   list_delete (el_list);
@@ -578,20 +578,17 @@
     oi->area->act_ints++;
 
   /* schedule router-LSA originate. */
-  ospf_router_lsa_timer_add (oi->area);
+  ospf_router_lsa_update_area (oi->area);
 
   /* Originate network-LSA. */
   if (old_state != ISM_DR && state == ISM_DR)
-    ospf_network_lsa_timer_add (oi);
+    ospf_network_lsa_update (oi);
   else if (old_state == ISM_DR && state != ISM_DR)
     {
       /* Free self originated network LSA. */
       lsa = oi->network_lsa_self;
       if (lsa)
-	{
-	  ospf_lsa_flush_area (lsa, oi->area);
-	  OSPF_TIMER_OFF (oi->t_network_lsa_self);
-	}
+        ospf_lsa_flush_area (lsa, oi->area);
 
       ospf_lsa_unlock (&oi->network_lsa_self);
       oi->network_lsa_self = NULL;
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index e708d5e..842df49 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -372,7 +372,7 @@
 
   lsah = (struct lsa_header *) STREAM_DATA (s);
 
-  lsah->ls_age = htons (0);
+  lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
   lsah->options = options;
   lsah->type = type;
   lsah->id = id;
@@ -741,7 +741,7 @@
   
   UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
   
-  ospf_router_lsa_timer_add (area);
+  ospf_router_lsa_update_area (area);
   
   return 0;
 }
@@ -885,6 +885,9 @@
   /* Delete LSA from neighbor retransmit-list. */
   ospf_ls_retransmit_delete_nbr_area (area, lsa);
 
+  /* Unregister LSA from refresh-list */
+  ospf_refresher_unregister_lsa (area->ospf, lsa);
+  
   /* Create new router-LSA instance. */
   if ( (new = ospf_router_lsa_new (area)) == NULL)
     {
@@ -910,20 +913,15 @@
   return NULL;
 }
 
-static int
-ospf_router_lsa_timer (struct thread *t)
+int
+ospf_router_lsa_update_area (struct ospf_area *area)
 {
-  struct ospf_area *area;
-
   if (IS_DEBUG_OSPF_EVENT)
-    zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
-
-  area = THREAD_ARG (t);
-  area->t_router_lsa_self = NULL;
+    zlog_debug ("[router-LSA]: (router-LSA area update)");
 
   /* Now refresh router-LSA. */
   if (area->router_lsa_self)
-    ospf_router_lsa_refresh (area->router_lsa_self);
+    ospf_lsa_refresh (area->ospf, area->router_lsa_self);
   /* Newly originate router-LSA. */
   else
     ospf_router_lsa_originate (area);
@@ -931,50 +929,15 @@
   return 0;
 }
 
-void
-ospf_router_lsa_timer_add (struct ospf_area *area)
-{
-  /* Keep area's self-originated router-LSA. */
-  struct ospf_lsa *lsa = area->router_lsa_self;
-
-  /* Cancel previously scheduled router-LSA timer. */
-  if (area->t_router_lsa_self)
-    if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
-      zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
-
-  OSPF_TIMER_OFF (area->t_router_lsa_self);
-
-  /* If router-LSA is originated previously, check the interval time. */
-  if (lsa)
-    {
-      int delay;
-      if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
-        {
-	  OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
-			      ospf_router_lsa_timer, delay);
-	  return;
-        }
-    }
-
-  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
-    zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
-
-  /* Immediately refresh router-LSA. */
-  OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
-}
-
 int
-ospf_router_lsa_update_timer (struct thread *thread)
+ospf_router_lsa_update (struct ospf *ospf)
 {
-  struct ospf *ospf = THREAD_ARG (thread);
   struct listnode *node, *nnode;
   struct ospf_area *area;
 
   if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
     zlog_debug ("Timer[router-LSA Update]: (timer expire)");
 
-  ospf->t_router_lsa_update = NULL;
-
   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
     {
       struct ospf_lsa *lsa = area->router_lsa_self;
@@ -999,19 +962,20 @@
 	  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
 	    zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
 		      lsa->data->type, inet_ntoa (lsa->data->id), area_str);
+          ospf_refresher_unregister_lsa (ospf, lsa);
 	  ospf_lsa_flush_area (lsa, area);
 	  ospf_lsa_unlock (&area->router_lsa_self);
 	  area->router_lsa_self = NULL;
 
 	  /* Refresh router-LSA, (not install) and flood through area. */
-	  ospf_router_lsa_timer_add (area);
+	  ospf_router_lsa_update_area (area);
 	}
       else
 	{
 	  rl = (struct router_lsa *) lsa->data;
 	  /* Refresh router-LSA, (not install) and flood through area. */
 	  if (rl->flags != ospf->flags)
-	    ospf_router_lsa_timer_add (area);
+	    ospf_router_lsa_update_area (area);
 	}
     }
 
@@ -1048,6 +1012,7 @@
   struct stream *s;
   struct ospf_lsa *new;
   struct lsa_header *lsah;
+  struct ospf_if_params *oip;
   int length;
 
   /* If there are no neighbours on this network (the net is stub),
@@ -1086,20 +1051,42 @@
   new->data = ospf_lsa_data_new (length);
   memcpy (new->data, lsah, length);
   stream_free (s);
-
+  
+  /* Remember prior network LSA sequence numbers, even if we stop
+   * originating one for this oi, to try avoid re-originating LSAs with a
+   * prior sequence number, and thus speed up adjency forming & convergence.
+   */
+  if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
+    {
+      new->data->ls_seqnum = oip->network_lsa_seqnum;
+      new->data->ls_seqnum = lsa_seqnum_increment (new);
+    }
+  else
+    {
+      oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
+      ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
+    }
+  oip->network_lsa_seqnum = new->data->ls_seqnum;
+  
   return new;
 }
 
 /* Originate network-LSA. */
-static struct ospf_lsa *
-ospf_network_lsa_originate (struct ospf_interface *oi)
+void
+ospf_network_lsa_update (struct ospf_interface *oi)
 {
   struct ospf_lsa *new;
-
+  
+  if (oi->network_lsa_self != NULL)
+    {
+      ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
+      return;
+    }
+  
   /* Create new network-LSA instance. */
   new = ospf_network_lsa_new (oi);
   if (new == NULL)
-    return NULL;
+    return;
 
   /* Install LSA to LSDB. */
   new = ospf_lsa_install (oi->ospf, oi, new);
@@ -1117,28 +1104,51 @@
       ospf_lsa_header_dump (new->data);
     }
 
-  return new;
+  return;
 }
 
-int
-ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
+static struct ospf_lsa *
+ospf_network_lsa_refresh (struct ospf_lsa *lsa)
 {
   struct ospf_area *area = lsa->area;
-  struct ospf_lsa *new;
-
+  struct ospf_lsa *new, *new2;
+  struct ospf_if_params *oip;
+  struct ospf_interface *oi;
+  
   assert (lsa->data);
-
+  
+  /* Retrieve the oi for the network LSA */
+  oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
+  if (oi == NULL)
+    {
+      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
+        {
+          zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
+                      "no oi found, ick, ignoring.",
+		      lsa->data->type, inet_ntoa (lsa->data->id));
+          ospf_lsa_header_dump (lsa->data);
+        }
+      return NULL;
+    }
   /* Delete LSA from neighbor retransmit-list. */
   ospf_ls_retransmit_delete_nbr_area (area, lsa);
 
+  /* Unregister LSA from refresh-list */
+  ospf_refresher_unregister_lsa (area->ospf, lsa);
+  
   /* Create new network-LSA instance. */
   new = ospf_network_lsa_new (oi);
   if (new == NULL)
-    return -1;
-  new->data->ls_seqnum = lsa_seqnum_increment (lsa);
+    return NULL;
+  
+  oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
+  assert (oip != NULL);
+  oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
 
-  ospf_lsa_install (area->ospf, oi, new);
-
+  new2 = ospf_lsa_install (area->ospf, oi, new);
+  
+  assert (new2 == new);
+  
   /* Flood LSA through aera. */
   ospf_flood_through_area (area, NULL, new);
 
@@ -1149,60 +1159,8 @@
       ospf_lsa_header_dump (new->data);
     }
 
-  return 0;
+  return new;
 }
-
-static int
-ospf_network_lsa_refresh_timer (struct thread *t)
-{
-  struct ospf_interface *oi;
-
-  oi = THREAD_ARG (t);
-  oi->t_network_lsa_self = NULL;
-
-  if (oi->network_lsa_self)
-    /* Now refresh network-LSA. */
-    ospf_network_lsa_refresh (oi->network_lsa_self, oi);
-  else
-    /* Newly create network-LSA. */
-    ospf_network_lsa_originate (oi);
-
-  return 0;
-}
-
-void
-ospf_network_lsa_timer_add (struct ospf_interface *oi)
-{
-  /* Keep interface's self-originated network-LSA. */
-  struct ospf_lsa *lsa = oi->network_lsa_self;
-
-  /* Cancel previously schedules network-LSA timer. */
-  if (oi->t_network_lsa_self)
-    if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
-      zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
-  OSPF_TIMER_OFF (oi->t_network_lsa_self);
-
-  /* If network-LSA is originated previously, check the interval time. */
-  if (lsa)
-    {
-      int delay;
-      if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
-        {
-          oi->t_network_lsa_self =
-            thread_add_timer (master, ospf_network_lsa_refresh_timer,
-			      oi, delay);
-          return;
-        }
-    }
-
-  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
-    zlog_debug ("Scheduling network-LSA origination right away");
-
-  /* Immediately refresh network-LSA. */
-  oi->t_network_lsa_self =
-    thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
-}
-
 
 static void
 stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
@@ -1326,7 +1284,7 @@
   return new;
 }
 
-struct ospf_lsa*
+static struct ospf_lsa*
 ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   struct ospf_lsa *new;
@@ -1473,7 +1431,7 @@
   return new;
 }
 
-struct ospf_lsa*
+static struct ospf_lsa*
 ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   struct ospf_lsa *new;
@@ -2299,6 +2257,7 @@
 	{
 	  if (IS_DEBUG_OSPF_EVENT)
 	    zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
+          ospf_refresher_unregister_lsa (ospf, lsa);
 	  ospf_lsa_flush_as (ospf, lsa);
 	}
     }
@@ -2327,7 +2286,7 @@
 }
 
 /* Refresh AS-external-LSA. */
-void
+struct ospf_lsa *
 ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
 			   struct external_info *ei, int force)
 {
@@ -2343,7 +2302,7 @@
                    lsa->data->type, inet_ntoa (lsa->data->id));
       ospf_external_lsa_flush (ospf, ei->type, &ei->p,
 			       ei->ifindex /*, ei->nexthop */);
-      return;
+      return NULL;
     }
 
   if (!changed && !force)
@@ -2351,7 +2310,7 @@
       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
         zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
                    lsa->data->type, inet_ntoa (lsa->data->id));
-      return;
+      return NULL;
     }
 
   /* Delete LSA from neighbor retransmit-list. */
@@ -2367,7 +2326,7 @@
       if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
 	zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
 		   inet_ntoa (lsa->data->id));
-      return;
+      return NULL;
     }
   
   new->data->ls_seqnum = lsa_seqnum_increment (lsa);
@@ -2396,7 +2355,7 @@
       ospf_lsa_header_dump (new->data);
     }
 
-  return;
+  return new;
 }
 
 
@@ -2404,8 +2363,8 @@
 
 /* Install router-LSA to an area. */
 static struct ospf_lsa *
-ospf_router_lsa_install (struct ospf *ospf,
-			 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;
 
@@ -2424,15 +2383,11 @@
       if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
 	return new; /* ignore stale LSA */
 
-      /* Set router-LSA refresh timer. */
-      OSPF_TIMER_OFF (area->t_router_lsa_self);
-      OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
-                          ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
-
       /* Set self-originated router-LSA. */
       ospf_lsa_unlock (&area->router_lsa_self);
       area->router_lsa_self = ospf_lsa_lock (new);
 
+      ospf_refresher_register_lsa (ospf, new);
     }
   if (rt_recalc)
     ospf_spf_calculate_schedule (ospf);
@@ -2465,15 +2420,9 @@
       if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
 	return new; /* ignore stale LSA */
 
-      /* Set LSRefresh timer. */
-      OSPF_TIMER_OFF (oi->t_network_lsa_self);
-
-      OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
-			       ospf_network_lsa_refresh_timer,
-			       OSPF_LS_REFRESH_TIME);
-
       ospf_lsa_unlock (&oi->network_lsa_self);
       oi->network_lsa_self = ospf_lsa_lock (new);
+      ospf_refresher_register_lsa (ospf, new);
     }
   if (rt_recalc)
     ospf_spf_calculate_schedule (ospf);
@@ -2721,7 +2670,8 @@
           if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
             {
       	      zlog_debug ("ospf_lsa_install() Premature Aging "
-		         "lsa 0x%lx", (u_long)lsa);
+		         "lsa 0x%p, seqnum 0x%x",
+		         lsa, ntohl(lsa->data->ls_seqnum));
       	      ospf_lsa_header_dump (lsa->data);
             }
         }
@@ -2826,7 +2776,7 @@
                    new->data->type, 
                    inet_ntoa (new->data->id), 
                    lsa);
-      ospf_lsa_maxage (ospf, lsa);
+      ospf_lsa_flush (ospf, lsa);
     }
 
   return new;
@@ -2858,35 +2808,6 @@
 }
 
 
-#ifdef ORIGINAL_CODING
-/* This function flood the maxaged LSA to DR. */
-void
-ospf_maxage_flood (struct ospf_lsa *lsa)
-{
-  switch (lsa->data->type)
-    {
-    case OSPF_ROUTER_LSA:
-    case OSPF_NETWORK_LSA:
-    case OSPF_SUMMARY_LSA:
-    case OSPF_ASBR_SUMMARY_LSA:
-    case OSPF_AS_NSSA_LSA:
-#ifdef HAVE_OPAQUE_LSA
-    case OSPF_OPAQUE_LINK_LSA:
-    case OSPF_OPAQUE_AREA_LSA:
-#endif /* HAVE_OPAQUE_LSA */
-      ospf_flood_through_area (lsa->area, NULL, lsa);
-      break;
-    case OSPF_AS_EXTERNAL_LSA:
-#ifdef HAVE_OPAQUE_LSA
-    case OSPF_OPAQUE_AS_LSA:
-#endif /* HAVE_OPAQUE_LSA */
-      ospf_flood_through_as (NULL, lsa);
-      break;
-    default:
-      break;
-    }
-}
-#endif /* ORIGINAL_CODING */
 
 static int
 ospf_maxage_lsa_remover (struct thread *thread)
@@ -2911,7 +2832,11 @@
             reschedule = 1;
             continue;
           }
-
+        
+        /* TODO: maybe convert this function to a work-queue */
+        if (thread_should_yield (thread))
+          OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
+          
         /* Remove LSA from the LSDB */
         if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
           if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
@@ -2922,19 +2847,11 @@
           zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
                      lsa->data->type, inet_ntoa (lsa->data->id));
 
-	/* Flood max age LSA. */
-#ifdef ORIGINAL_CODING
-	ospf_maxage_flood (lsa);
-#else /* ORIGINAL_CODING */
-        ospf_flood_through (ospf, NULL, lsa);
-#endif /* ORIGINAL_CODING */
-
-	if (lsa->flags & OSPF_LSA_PREMATURE_AGE)  
+	if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
           {
             if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
-              zlog_debug ("originating new router lsa for lsa 0x%lx \n", 
-                         (u_long)lsa);
-            ospf_router_lsa_originate(lsa->area);
+              zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
+            ospf_lsa_refresh (ospf, lsa);
           }
 
 	/* Remove from lsdb. */
@@ -2953,7 +2870,8 @@
         neighbor Link state retransmission lists and b) none of the router's
         neighbors are in states Exchange or Loading. */
   if (reschedule)
-    OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
+    OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
+                   ospf->maxage_delay);
 
   return 0;
 }
@@ -2971,6 +2889,11 @@
     }
 }
 
+/* Add LSA onto the MaxAge list, and schedule for removal.
+ * This does *not* lead to the LSA being flooded, that must be taken
+ * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
+ * function).
+ */
 void
 ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
 {
@@ -2990,7 +2913,8 @@
   if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
     zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
 
-  OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
+  OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
+                 ospf->maxage_delay);
 }
 
 static int
@@ -3035,6 +2959,10 @@
 	ospf_lsa_maxage (ospf, lsa);
       }
 
+  if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
+    if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
+      printf ("Eek! Shouldn't happen!\n");
+
   return 0;
 }
 
@@ -3353,6 +3281,7 @@
   switch (lsa->data->type)
     {
 #ifdef HAVE_OPAQUE_LSA
+    /* Opaque wants to be notified of flushes */
     case OSPF_OPAQUE_LINK_LSA:
     case OSPF_OPAQUE_AREA_LSA:
     case OSPF_OPAQUE_AS_LSA:
@@ -3360,7 +3289,8 @@
       break;
 #endif /* HAVE_OPAQUE_LSA */
     default:
-      ospf_lsa_maxage (ospf, lsa);
+      ospf_refresher_unregister_lsa (ospf, lsa);
+      ospf_lsa_flush (ospf, lsa);
       break;
     }
 
@@ -3383,12 +3313,13 @@
       if ((lsa = area->router_lsa_self) != NULL)
         {
           if (IS_DEBUG_OSPF_EVENT)
-            zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
-
+            zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
+                        lsa->data->type, inet_ntoa (lsa->data->id));
+          
+          ospf_refresher_unregister_lsa (ospf, lsa);
           ospf_lsa_flush_area (lsa, area);
           ospf_lsa_unlock (&area->router_lsa_self);
           area->router_lsa_self = NULL;
-          OSPF_TIMER_OFF (area->t_router_lsa_self);
         }
 
       for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
@@ -3398,12 +3329,13 @@
                &&   oi->full_nbrs > 0)
             {
               if (IS_DEBUG_OSPF_EVENT)
-                zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
-
+                zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
+                            lsa->data->type, inet_ntoa (lsa->data->id));
+              
+              ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
               ospf_lsa_flush_area (oi->network_lsa_self, area);
               ospf_lsa_unlock (&oi->network_lsa_self);
               oi->network_lsa_self = NULL;
-              OSPF_TIMER_OFF (oi->t_network_lsa_self);
             }
 
           if (oi->type != OSPF_IFTYPE_VIRTUALLINK
@@ -3603,23 +3535,28 @@
 
 
 /* LSA Refreshment functions. */
-static void
+struct ospf_lsa *
 ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
 {
   struct external_info *ei;
+  struct ospf_lsa *new = NULL;
   assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
+  assert (lsa->lock > 0);
 
   switch (lsa->data->type)
     {
       /* Router and Network LSAs are processed differently. */
     case OSPF_ROUTER_LSA:
+      new = ospf_router_lsa_refresh (lsa);
+      break;
     case OSPF_NETWORK_LSA: 
+      new = ospf_network_lsa_refresh (lsa);
       break;
     case OSPF_SUMMARY_LSA:
-      ospf_summary_lsa_refresh (ospf, lsa);
+      new = ospf_summary_lsa_refresh (ospf, lsa);
       break;
     case OSPF_ASBR_SUMMARY_LSA:
-      ospf_summary_asbr_lsa_refresh (ospf, lsa);
+      new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
       break;
     case OSPF_AS_EXTERNAL_LSA:
       /* Translated from NSSA Type-5s are refreshed when 
@@ -3629,7 +3566,7 @@
         break;
       ei = ospf_external_info_check (lsa);
       if (ei)
-        ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
+        new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
       else
         ospf_lsa_flush_as (ospf, lsa);
       break;
@@ -3637,12 +3574,13 @@
     case OSPF_OPAQUE_LINK_LSA:
     case OSPF_OPAQUE_AREA_LSA:
     case OSPF_OPAQUE_AS_LSA:
-      ospf_opaque_lsa_refresh (lsa);
+      new = ospf_opaque_lsa_refresh (lsa);
       break;
 #endif /* HAVE_OPAQUE_LSA */
     default:
       break;
     }
+  return new;
 }
 
 void
@@ -3650,6 +3588,7 @@
 {
   u_int16_t index, current_index;
   
+  assert (lsa->lock > 0);
   assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
 
   if (lsa->refresh_list < 0)
@@ -3668,11 +3607,11 @@
       if (delay < 0)
 	delay = 0;
 
-      current_index = ospf->lsa_refresh_queue.index +
-	(quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
+      current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
+                - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
       
       index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
-	% (OSPF_LSA_REFRESHER_SLOTS);
+	      % (OSPF_LSA_REFRESHER_SLOTS);
 
       if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
 	zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
@@ -3692,6 +3631,7 @@
 void
 ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
 {
+  assert (lsa->lock > 0);
   assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
   if (lsa->refresh_list >= 0)
     {
@@ -3728,8 +3668,9 @@
      modulus. */
   ospf->lsa_refresh_queue.index =
    ((unsigned long)(ospf->lsa_refresh_queue.index +
-		    (quagga_time (NULL) - ospf->lsa_refresher_started) /
-		    OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
+		    (quagga_time (NULL) - ospf->lsa_refresher_started)
+		    / OSPF_LSA_REFRESHER_GRANULARITY))
+		    % OSPF_LSA_REFRESHER_SLOTS;
 
   if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
     zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
@@ -3744,6 +3685,8 @@
 
       refresh_list = ospf->lsa_refresh_queue.qs [i];
       
+      assert (i >= 0);
+
       ospf->lsa_refresh_queue.qs [i] = NULL;
 
       if (refresh_list)
@@ -3755,8 +3698,8 @@
 		           "refresh lsa %p (slot %d)", 
 		           inet_ntoa (lsa->data->id), lsa, i);
 	      
+	      assert (lsa->lock > 0);
 	      list_delete_node (refresh_list, node);
-	      ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
 	      lsa->refresh_list = -1;
 	      listnode_add (lsa_to_refresh, lsa);
 	    }
@@ -3769,7 +3712,11 @@
   ospf->lsa_refresher_started = quagga_time (NULL);
 
   for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
-    ospf_lsa_refresh (ospf, lsa);
+    {
+      ospf_lsa_refresh (ospf, lsa);
+      assert (lsa->lock > 0);
+      ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
+    }
   
   list_delete (lsa_to_refresh);
   
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index 251d473..72e2f8a 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -114,11 +114,9 @@
 
   /* Refreshement List or Queue */
   int refresh_list;
-
-#ifdef HAVE_OPAQUE_LSA
-  /* For Type-9 Opaque-LSAs, reference to ospf-interface is required. */
+  
+  /* For Type-9 Opaque-LSAs */
   struct ospf_interface *oi;
-#endif /* HAVE_OPAQUE_LSA */
 };
 
 /* OSPF LSA Link Type. */
@@ -254,19 +252,16 @@
 extern void ospf_lsa_data_free (struct lsa_header *);
 
 /* Prototype for various LSAs */
-extern int ospf_router_lsa_update_timer (struct thread *);
-extern void ospf_router_lsa_timer_add (struct ospf_area *);
+extern int ospf_router_lsa_update (struct ospf *);
+extern int ospf_router_lsa_update_area (struct ospf_area *);
 
-extern int ospf_network_lsa_refresh (struct ospf_lsa *, struct ospf_interface *);
-extern void ospf_network_lsa_timer_add (struct ospf_interface *);
+extern void ospf_network_lsa_update (struct ospf_interface *);
 
 extern struct ospf_lsa *ospf_summary_lsa_originate (struct prefix_ipv4 *, u_int32_t,
 					     struct ospf_area *);
 extern struct ospf_lsa *ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *,
 						  u_int32_t,
 						  struct ospf_area *);
-extern struct ospf_lsa *ospf_summary_lsa_refresh (struct ospf *, struct ospf_lsa *);
-extern struct ospf_lsa *ospf_summary_asbr_lsa_refresh (struct ospf *, struct ospf_lsa *);
 
 extern struct ospf_lsa *ospf_lsa_install (struct ospf *,
 				   struct ospf_interface *, struct ospf_lsa *);
@@ -300,12 +295,15 @@
 extern u_int32_t get_metric (u_char *);
 
 extern int ospf_lsa_maxage_walker (struct thread *);
-
+extern struct ospf_lsa *ospf_lsa_refresh (struct ospf *, struct ospf_lsa *);
+ 
 extern void ospf_external_lsa_refresh_default (struct ospf *);
 
 extern void ospf_external_lsa_refresh_type (struct ospf *, u_char, int);
-extern void ospf_external_lsa_refresh (struct ospf *, struct ospf_lsa *,
-				struct external_info *, int);
+extern struct ospf_lsa *ospf_external_lsa_refresh (struct ospf *,
+                                                   struct ospf_lsa *,
+                                                   struct external_info *,
+                                                   int);
 extern struct in_addr ospf_lsa_unique_id (struct ospf *, struct ospf_lsdb *, u_char,
 				   struct prefix_ipv4 *);
 extern void ospf_schedule_lsa_flood_area (struct ospf_area *, struct ospf_lsa *);
diff --git a/ospfd/ospf_lsdb.c b/ospfd/ospf_lsdb.c
index c906f05..ea9a352 100644
--- a/ospfd/ospf_lsdb.c
+++ b/ospfd/ospf_lsdb.c
@@ -120,7 +120,10 @@
   
   /* nothing to do? */
   if (rn->info && rn->info == lsa)
-    return;
+    {
+      route_unlock_node (rn);
+      return;
+    }
   
   /* purge old entry? */
   if (rn->info)
@@ -162,12 +165,13 @@
       return;
     }
   
+  assert (lsa->data->type < OSPF_MAX_LSA);
   table = lsdb->type[lsa->data->type].db;
   lsdb_prefix_set (&lp, lsa);
-  rn = route_node_lookup (table, (struct prefix *) &lp);
-  if (rn && (rn->info == lsa))
+  if ((rn = route_node_lookup (table, (struct prefix *) &lp)))
     {
-      ospf_lsdb_delete_entry (lsdb, rn);
+      if (rn->info == lsa)
+        ospf_lsdb_delete_entry (lsdb, rn);
       route_unlock_node (rn); /* route_node_lookup */
     }
 }
@@ -274,7 +278,8 @@
       rn = route_top (table);
   else
     {
-      rn = route_node_get (table, (struct prefix *) &lp);
+      if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL)
+        return NULL;
       rn = route_next (rn);
     }
 
diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c
index 89ff203..1e2d44e 100644
--- a/ospfd/ospf_network.c
+++ b/ospfd/ospf_network.c
@@ -61,7 +61,7 @@
 	       "on # of multicast group memberships has been exceeded?",
                top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
   else
-    zlog_info ("interface %s [%u] join AllSPFRouters Multicast group.",
+    zlog_debug ("interface %s [%u] join AllSPFRouters Multicast group.",
 	       inet_ntoa (p->u.prefix4), ifindex);
 
   return ret;
@@ -81,8 +81,8 @@
 	       "ifindex %u, AllSPFRouters): %s",
                top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
   else
-    zlog_info ("interface %s [%u] leave AllSPFRouters Multicast group.",
-	       inet_ntoa (p->u.prefix4), ifindex);
+    zlog_debug ("interface %s [%u] leave AllSPFRouters Multicast group.",
+	        inet_ntoa (p->u.prefix4), ifindex);
 
   return ret;
 }
@@ -103,8 +103,8 @@
 	       "on # of multicast group memberships has been exceeded?",
                top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
   else
-    zlog_info ("interface %s [%u] join AllDRouters Multicast group.",
-	       inet_ntoa (p->u.prefix4), ifindex);
+    zlog_debug ("interface %s [%u] join AllDRouters Multicast group.",
+	        inet_ntoa (p->u.prefix4), ifindex);
 
   return ret;
 }
@@ -123,8 +123,8 @@
 	       "ifindex %u, AllDRouters): %s",
                top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
   else
-    zlog_info ("interface %s [%u] leave AllDRouters Multicast group.",
-	       inet_ntoa (p->u.prefix4), ifindex);
+    zlog_debug ("interface %s [%u] leave AllDRouters Multicast group.",
+	        inet_ntoa (p->u.prefix4), ifindex);
 
   return ret;
 }
diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c
index 15fff34..cbc3171 100644
--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -162,7 +162,7 @@
 
 /* OSPF NSM functions. */
 static int
-nsm_hello_received (struct ospf_neighbor *nbr)
+nsm_packet_received (struct ospf_neighbor *nbr)
 {
   /* Start or Restart Inactivity Timer. */
   OSPF_NSM_TIMER_OFF (nbr->t_inactivity);
@@ -216,7 +216,7 @@
     {
     case OSPF_OPAQUE_LINK_LSA:
       /* Exclude type-9 LSAs that does not have the same "oi" with "nbr". */
-      if (lsa->oi != nbr->oi)
+      if (nbr->oi && ospf_if_exists (lsa->oi) != nbr->oi)
           return 0;
       break;
     case OSPF_OPAQUE_AREA_LSA:
@@ -408,7 +408,7 @@
   {
     /* DependUpon: dummy state. */
     { NULL,                    NSM_DependUpon }, /* NoEvent           */
-    { NULL,                    NSM_DependUpon }, /* HelloReceived     */
+    { NULL,                    NSM_DependUpon }, /* PacketReceived    */
     { NULL,                    NSM_DependUpon }, /* Start             */
     { NULL,                    NSM_DependUpon }, /* 2-WayReceived     */
     { NULL,                    NSM_DependUpon }, /* NegotiationDone   */
@@ -425,7 +425,7 @@
   {
     /* Deleted: dummy state. */
     { NULL,                    NSM_Deleted    }, /* NoEvent           */
-    { NULL,                    NSM_Deleted    }, /* HelloReceived     */
+    { NULL,                    NSM_Deleted    }, /* PacketReceived    */
     { NULL,                    NSM_Deleted    }, /* Start             */
     { NULL,                    NSM_Deleted    }, /* 2-WayReceived     */
     { NULL,                    NSM_Deleted    }, /* NegotiationDone   */
@@ -442,7 +442,7 @@
   {
     /* Down: */
     { NULL,                    NSM_DependUpon }, /* NoEvent           */
-    { nsm_hello_received,      NSM_Init       }, /* HelloReceived     */
+    { nsm_packet_received,     NSM_Init       }, /* PacketReceived    */
     { nsm_start,               NSM_Attempt    }, /* Start             */
     { NULL,                    NSM_Down       }, /* 2-WayReceived     */
     { NULL,                    NSM_Down       }, /* NegotiationDone   */
@@ -459,7 +459,7 @@
   {
     /* Attempt: */
     { NULL,                    NSM_DependUpon }, /* NoEvent           */
-    { nsm_hello_received,      NSM_Init       }, /* HelloReceived     */
+    { nsm_packet_received,     NSM_Init       }, /* PacketReceived    */
     { NULL,                    NSM_Attempt    }, /* Start             */
     { NULL,                    NSM_Attempt    }, /* 2-WayReceived     */
     { NULL,                    NSM_Attempt    }, /* NegotiationDone   */
@@ -476,7 +476,7 @@
   {
     /* Init: */
     { NULL,                    NSM_DependUpon }, /* NoEvent           */
-    { nsm_hello_received,      NSM_Init       }, /* HelloReceived     */
+    { nsm_packet_received,     NSM_Init      }, /* PacketReceived    */
     { NULL,                    NSM_Init       }, /* Start             */
     { nsm_twoway_received,     NSM_DependUpon }, /* 2-WayReceived     */
     { NULL,                    NSM_Init       }, /* NegotiationDone   */
@@ -493,7 +493,7 @@
   {
     /* 2-Way: */
     { NULL,                    NSM_DependUpon }, /* NoEvent           */
-    { nsm_hello_received,      NSM_TwoWay     }, /* HelloReceived     */
+    { nsm_packet_received,     NSM_TwoWay     }, /* HelloReceived     */
     { NULL,                    NSM_TwoWay     }, /* Start             */
     { NULL,                    NSM_TwoWay     }, /* 2-WayReceived     */
     { NULL,                    NSM_TwoWay     }, /* NegotiationDone   */
@@ -510,7 +510,7 @@
   {
     /* ExStart: */
     { NULL,                    NSM_DependUpon }, /* NoEvent           */
-    { nsm_hello_received,      NSM_ExStart    }, /* HelloReceived     */
+    { nsm_packet_received,     NSM_ExStart    }, /* PacaketReceived   */
     { NULL,                    NSM_ExStart    }, /* Start             */
     { NULL,                    NSM_ExStart    }, /* 2-WayReceived     */
     { nsm_negotiation_done,    NSM_Exchange   }, /* NegotiationDone   */
@@ -527,7 +527,7 @@
   {
     /* Exchange: */
     { NULL,                    NSM_DependUpon }, /* NoEvent           */
-    { nsm_hello_received,      NSM_Exchange   }, /* HelloReceived     */
+    { nsm_packet_received,     NSM_Exchange   }, /* PacketReceived    */
     { NULL,                    NSM_Exchange   }, /* Start             */
     { NULL,                    NSM_Exchange   }, /* 2-WayReceived     */
     { NULL,                    NSM_Exchange   }, /* NegotiationDone   */
@@ -544,7 +544,7 @@
   {
     /* Loading: */
     { NULL,                    NSM_DependUpon }, /* NoEvent           */
-    { nsm_hello_received,      NSM_Loading    }, /* HelloReceived     */
+    { nsm_packet_received,     NSM_Loading    }, /* PacketReceived    */
     { NULL,                    NSM_Loading    }, /* Start             */
     { NULL,                    NSM_Loading    }, /* 2-WayReceived     */
     { NULL,                    NSM_Loading    }, /* NegotiationDone   */
@@ -560,7 +560,7 @@
   },
   { /* Full: */
     { NULL,                    NSM_DependUpon }, /* NoEvent           */
-    { nsm_hello_received,      NSM_Full       }, /* HelloReceived     */
+    { nsm_packet_received,     NSM_Full       }, /* PacketReceived    */
     { NULL,                    NSM_Full       }, /* Start             */
     { NULL,                    NSM_Full       }, /* 2-WayReceived     */
     { NULL,                    NSM_Full       }, /* NegotiationDone   */
@@ -579,7 +579,7 @@
 static const char *ospf_nsm_event_str[] =
 {
   "NoEvent",
-  "HelloReceived",
+  "PacketReceived",
   "Start",
   "2-WayReceived",
   "NegotiationDone",
@@ -711,7 +711,7 @@
 		 LOOKUP(ospf_nsm_state_msg, old_state),
 		 LOOKUP(ospf_nsm_state_msg, state));
 
-      ospf_router_lsa_timer_add (oi->area);
+      ospf_router_lsa_update_area (oi->area);
 
       if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
 	{
@@ -719,7 +719,7 @@
 	    ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id);
 	  
 	  if (vl_area)
-	    ospf_router_lsa_timer_add (vl_area);
+	    ospf_router_lsa_update_area (vl_area);
 	}
 
       /* Originate network-LSA. */
@@ -730,10 +730,9 @@
 	      ospf_lsa_flush_area (oi->network_lsa_self, oi->area);
 	      ospf_lsa_unlock (&oi->network_lsa_self);
 	      oi->network_lsa_self = NULL;
-	      OSPF_TIMER_OFF (oi->t_network_lsa_self);
 	    }
 	  else
-	    ospf_network_lsa_timer_add (oi);
+	    ospf_network_lsa_update (oi);
 	}
     }
 
diff --git a/ospfd/ospf_nsm.h b/ospfd/ospf_nsm.h
index 1121dae..4f2ae80 100644
--- a/ospfd/ospf_nsm.h
+++ b/ospfd/ospf_nsm.h
@@ -39,7 +39,7 @@
 
 /* OSPF Neighbor State Machine Event. */
 #define NSM_NoEvent	        0
-#define NSM_HelloReceived	1
+#define NSM_PacketReceived	1 /* HelloReceived in the protocol */
 #define NSM_Start		2
 #define NSM_TwoWayReceived	3
 #define NSM_NegotiationDone	4
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 0b6ac4c..aa126e1 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -251,7 +251,7 @@
   void (* config_write_debug )(struct vty *vty);
   void (* show_opaque_info   )(struct vty *vty, struct ospf_lsa *lsa);
   int  (* lsa_originator)(void *arg);
-  void (* lsa_refresher )(struct ospf_lsa *lsa);
+  struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa);
   int (* new_lsa_hook)(struct ospf_lsa *lsa);
   int (* del_lsa_hook)(struct ospf_lsa *lsa);
 };
@@ -354,7 +354,7 @@
   void (* config_write_debug )(struct vty *vty),
   void (* show_opaque_info   )(struct vty *vty, struct ospf_lsa *lsa),
   int  (* lsa_originator)(void *arg),
-  void (* lsa_refresher )(struct ospf_lsa *lsa),
+  struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa),
   int (* new_lsa_hook)(struct ospf_lsa *lsa),
   int (* del_lsa_hook)(struct ospf_lsa *lsa))
 {
@@ -1608,12 +1608,13 @@
   return new;
 }
 
-void
+struct ospf_lsa *
 ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)
 {
   struct ospf *ospf;
   struct ospf_opaque_functab *functab;
-
+  struct ospf_lsa *new = NULL;
+  
   ospf = ospf_lookup ();
 
   if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL
@@ -1630,12 +1631,12 @@
         zlog_debug ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa->data->type, inet_ntoa (lsa->data->id));
 
       lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
-      ospf_lsa_maxage (ospf, lsa);
+      ospf_lsa_flush (ospf, lsa);
     }
   else
-    (* functab->lsa_refresher)(lsa);
+    new = (* functab->lsa_refresher)(lsa);
 
-  return;
+  return new;
 }
 
 /*------------------------------------------------------------------------*
@@ -2108,7 +2109,7 @@
     zlog_debug ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
 
   /* This lsa will be flushed and removed eventually. */
-  ospf_lsa_maxage (lsa0->area->ospf, lsa);
+  ospf_lsa_flush (lsa0->area->ospf, lsa);
 
 out:
   return;
diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h
index f49fe46..2273064 100644
--- a/ospfd/ospf_opaque.h
+++ b/ospfd/ospf_opaque.h
@@ -120,7 +120,7 @@
   void (* config_write_debug )(struct vty *vty),
   void (* show_opaque_info   )(struct vty *vty, struct ospf_lsa *lsa),
   int  (* lsa_originator)(void *arg),
-  void (* lsa_refresher )(struct ospf_lsa *lsa),
+  struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa),
   int (* new_lsa_hook)(struct ospf_lsa *lsa),
   int (* del_lsa_hook)(struct ospf_lsa *lsa)
 );
@@ -143,7 +143,7 @@
 						int *init_delay);
 extern struct ospf_lsa *ospf_opaque_lsa_install (struct ospf_lsa *,
 						 int rt_recalc);
-extern void ospf_opaque_lsa_refresh (struct ospf_lsa *lsa);
+extern struct ospf_lsa *ospf_opaque_lsa_refresh (struct ospf_lsa *lsa);
 
 extern void ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent,
 						  u_char lsa_type,
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 1b68fd5..be137d9 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -125,6 +125,20 @@
   fifo->count++;
 }
 
+/* Add new packet to head of fifo. */
+static void
+ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op)
+{
+  op->next = fifo->head;
+  
+  if (fifo->tail == NULL)
+    fifo->tail = op;
+  
+  fifo->head = op;
+  
+  fifo->count++;
+}
+
 /* Delete first packet from fifo. */
 struct ospf_packet *
 ospf_fifo_pop (struct ospf_fifo *fifo)
@@ -199,6 +213,27 @@
   /* ospf_fifo_debug (oi->obuf); */
 }
 
+static void
+ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)
+{
+  if (!oi->obuf)
+    {
+      zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
+	       "destination %s) called with NULL obuf, ignoring "
+	       "(please report this bug)!\n",
+	       IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
+	       ospf_packet_type_str[stream_getc_from(op->s, 1)],
+	       inet_ntoa (op->dst));
+      return;
+    }
+
+  /* Add packet to head of queue. */
+  ospf_fifo_push_head (oi->obuf, op);
+
+  /* Debug of packet fifo*/
+  /* ospf_fifo_debug (oi->obuf); */
+}
+
 void
 ospf_packet_delete (struct ospf_interface *oi)
 {
@@ -888,7 +923,7 @@
   old_state = nbr->state;
 
   /* Add event to thread. */
-  OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
+  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
 
   /*  RFC2328  Section 9.5.1
       If the router is not eligible to become Designated Router,
@@ -908,7 +943,7 @@
   if (oi->type == OSPF_IFTYPE_NBMA &&
       (old_state == NSM_Down || old_state == NSM_Attempt))
     {
-      OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
+      OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
       nbr->priority = hello->priority;
       nbr->d_router = hello->d_router;
       nbr->bd_router = hello->bd_router;
@@ -918,12 +953,12 @@
   if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
 			      size - OSPF_HELLO_MIN_SIZE))
     {
-      OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
+      OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);
       nbr->options |= hello->options;
     }
   else
     {
-      OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
+      OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);
       /* Set neighbor information. */
       nbr->priority = hello->priority;
       nbr->d_router = hello->d_router;
@@ -1198,6 +1233,9 @@
     }
 #endif /* HAVE_OPAQUE_LSA */
 
+  /* Add event to thread. */
+  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
+
   /* Process DD packet by neighbor status. */
   switch (nbr->state)
     {
@@ -1419,6 +1457,9 @@
       return;
     }
 
+  /* Add event to thread. */
+  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
+
   /* Neighbor State should be Exchange or later. */
   if (nbr->state != NSM_Exchange &&
       nbr->state != NSM_Loading &&
@@ -1651,6 +1692,9 @@
       return;
     }
 
+  /* Add event to thread. */
+  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
+
   /* Check neighbor state. */
   if (nbr->state < NSM_Exchange)
     {
@@ -1953,7 +1997,7 @@
 	      quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
 	      
 	      if (tv_cmp (tv_sub (now, current->tv_orig), 
-			  int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
+			  int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)
 		/* Trap NSSA type later.*/
 		ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
 	      DISCARD_LSA (lsa, 8);
@@ -1984,6 +2028,9 @@
       return;
     }
 
+  /* Add event to thread. */
+  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);
+
   if (nbr->state < NSM_Exchange)
     {
       zlog_warn ("Link State Acknowledgment: "
@@ -2971,8 +3018,8 @@
   return length;
 }
 
-void
-ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
+static void
+ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)
 {
   struct ospf_packet *op;
   u_int16_t length = OSPF_HEADER_SIZE;
@@ -2991,10 +3038,12 @@
   /* Set packet length. */
   op->length = length;
 
-  op->dst.s_addr = addr->s_addr;
+  op->dst.s_addr = addr;
 
-  /* Add packet to the interface output queue. */
-  ospf_packet_add (oi, op);
+  /* Add packet to the top of the interface output queue, so that they
+   * can't get delayed by things like long queues of LS Update packets
+   */
+  ospf_packet_add_top (oi, op);
 
   /* Hook thread to write packet. */
   OSPF_ISM_WRITE_ON (oi->ospf);
@@ -3025,7 +3074,7 @@
       && oi->state != ISM_DR && oi->state != ISM_Backup)
     return;
 
-  ospf_hello_send_sub (oi, &nbr_nbma->addr);
+  ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);
 }
 
 int
@@ -3064,7 +3113,7 @@
     zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
 	  IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
 
-  ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
+  ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);
 
   return 0;
 }
@@ -3073,27 +3122,10 @@
 void
 ospf_hello_send (struct ospf_interface *oi)
 {
-  struct ospf_packet *op;
-  u_int16_t length = OSPF_HEADER_SIZE;
-
   /* If this is passive interface, do not send OSPF Hello. */
   if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
     return;
 
-  op = ospf_packet_new (oi->ifp->mtu);
-
-  /* Prepare OSPF common header. */
-  ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
-
-  /* Prepare OSPF Hello body. */
-  length += ospf_make_hello (oi, op->s);
-
-  /* Fill OSPF header. */
-  ospf_fill_header (oi, op->s, length);
-
-  /* Set packet length. */
-  op->length = length;
-
   if (oi->type == OSPF_IFTYPE_NBMA)
     {
       struct ospf_neighbor *nbr;
@@ -3123,34 +3155,16 @@
 		if (nbr->priority == 0 && oi->state == ISM_DROther)
 		  continue;
 		/* if oi->state == Waiting, send hello to all neighbors */
-		{
-		  struct ospf_packet *op_dup;
-
-		  op_dup = ospf_packet_dup(op);
-		  op_dup->dst = nbr->address.u.prefix4;
-
-		  /* Add packet to the interface output queue. */
-		  ospf_packet_add (oi, op_dup);
-
-		  OSPF_ISM_WRITE_ON (oi->ospf);
-		}
-
+		ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);
 	      }
-      ospf_packet_free (op);
     }
   else
     {
       /* Decide destination address. */
       if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
-	op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
-      else 
-	op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
-
-      /* Add packet to the interface output queue. */
-      ospf_packet_add (oi, op);
-
-      /* Hook thread to write packet. */
-      OSPF_ISM_WRITE_ON (oi->ospf);
+        ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr);
+      else
+        ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));
     }
 }
 
diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h
index 7b3d686..9a47208 100644
--- a/ospfd/ospf_packet.h
+++ b/ospfd/ospf_packet.h
@@ -162,6 +162,5 @@
 extern int ospf_ls_ack_timer (struct thread *);
 extern int ospf_poll_timer (struct thread *);
 extern int ospf_hello_reply_timer (struct thread *);
-extern void ospf_hello_send_sub (struct ospf_interface *, struct in_addr *);
 
 #endif /* _ZEBRA_OSPF_PACKET_H */
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index c5ec0ad..24e8105 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -133,7 +133,7 @@
 static void ospf_mpls_te_config_write_if (struct vty *vty, struct interface *ifp);
 static void ospf_mpls_te_show_info (struct vty *vty, struct ospf_lsa *lsa);
 static int ospf_mpls_te_lsa_originate (void *arg);
-static void ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa);
+static struct ospf_lsa *ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa);
 static void ospf_mpls_te_lsa_schedule (struct mpls_te_link *lp, enum sched_opcode);
 
 static void del_mpls_te_link (void *val);
@@ -1009,7 +1009,7 @@
   return rc;
 }
 
-static void
+static struct ospf_lsa *
 ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa)
 {
   struct mpls_te_link *lp;
@@ -1070,7 +1070,7 @@
     }
 
 out:
-  return;
+  return new;
 }
 
 static void
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index adc822a..46e7ffa 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -2933,7 +2933,13 @@
 		       inet_ntoa (nbr->address.u.prefix4), VTY_NEWLINE);
 	    }
 	}
-
+      
+      /* Next network-LSA sequence number we'll use, if we're elected DR */
+      if (oi->params && ntohl (oi->params->network_lsa_seqnum)
+                          != OSPF_INITIAL_SEQUENCE_NUMBER)
+        vty_out (vty, "  Saved Network-LSA sequence number 0x%x%s",
+                 ntohl (oi->params->network_lsa_seqnum), VTY_NEWLINE);
+      
       vty_out (vty, "  Multicast group memberships:");
       if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)
           || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
@@ -7023,7 +7029,7 @@
       SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
       
       if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
-          ospf_router_lsa_timer_add (area);
+          ospf_router_lsa_update_area (area);
     }
   return CMD_SUCCESS;
 }
@@ -7049,7 +7055,7 @@
           && !area->t_stub_router)
         {
           UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
-          ospf_router_lsa_timer_add (area);
+          ospf_router_lsa_update_area (area);
         }
     }
   return CMD_SUCCESS;
@@ -7102,7 +7108,7 @@
       if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
         {
           UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
-          ospf_router_lsa_timer_add (area);
+          ospf_router_lsa_update_area (area);
         }
     }
   return CMD_SUCCESS;
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index a7553e7..0188ffd 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -131,8 +131,8 @@
 	  ospf->external_origin = 0;
 	}
 
-      OSPF_TIMER_ON (ospf->t_router_lsa_update,
-		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
+      /* update router-lsa's for each area */
+      ospf_router_lsa_update (ospf);
       
       /* update ospf_interface's */
       for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
@@ -199,6 +199,7 @@
   new->spf_hold_multiplier = 1;
 
   /* MaxAge init. */
+  new->maxage_delay = OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
   new->maxage_lsa = list_new ();
   new->t_maxage_walker =
     thread_add_timer (master, ospf_lsa_maxage_walker,
@@ -337,7 +338,7 @@
           SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
           
           if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
-              ospf_router_lsa_timer_add (area);
+            ospf_router_lsa_update_area (area);
         }
       timeout = ospf->stub_router_shutdown_time;
     }
@@ -473,7 +474,6 @@
 
   /* Cancel all timers. */
   OSPF_TIMER_OFF (ospf->t_external_lsa);
-  OSPF_TIMER_OFF (ospf->t_router_lsa_update);
   OSPF_TIMER_OFF (ospf->t_spf_calc);
   OSPF_TIMER_OFF (ospf->t_ase_calc);
   OSPF_TIMER_OFF (ospf->t_maxage);
@@ -631,7 +631,6 @@
     free (IMPORT_NAME (area));
 
   /* Cancel timer. */
-  OSPF_TIMER_OFF (area->t_router_lsa_self);
   OSPF_TIMER_OFF (area->t_stub_router);
 #ifdef HAVE_OPAQUE_LSA
   OSPF_TIMER_OFF (area->t_opaque_lsa_self);
@@ -1041,7 +1040,7 @@
       break;
     }
 
-  ospf_router_lsa_timer_add (area);
+  ospf_router_lsa_update_area (area);
   ospf_schedule_abr_task (area->ospf);
 }
 
@@ -1052,7 +1051,7 @@
     return 0;
 
   area->shortcut_configured = mode;
-  ospf_router_lsa_timer_add (area);
+  ospf_router_lsa_update_area (area);
   ospf_schedule_abr_task (ospf);
 
   ospf_area_check_free (ospf, area->area_id);
@@ -1064,7 +1063,7 @@
 ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
 {
   area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
-  ospf_router_lsa_timer_add (area);
+  ospf_router_lsa_update_area (area);
   ospf_area_check_free (ospf, area->area_id);
   ospf_schedule_abr_task (ospf);
 
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index b24b3ce..0e57c45 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -58,6 +58,7 @@
 #endif
 #define OSPF_MIN_LS_INTERVAL                     5
 #define OSPF_MIN_LS_ARRIVAL                      1
+#define OSPF_LSA_INITIAL_AGE                     0	/* useful for debug */
 #define OSPF_LSA_MAXAGE                       3600
 #define OSPF_CHECK_AGE                         300
 #define OSPF_LSA_MAXAGE_DIFF                   900
@@ -66,7 +67,6 @@
 #define OSPF_INITIAL_SEQUENCE_NUMBER    0x80000001
 #define OSPF_MAX_SEQUENCE_NUMBER        0x7fffffff
 
-#define OSPF_LSA_MAXAGE_CHECK_INTERVAL          30
 #define OSPF_NSSA_TRANS_STABLE_DEFAULT		40
 
 #define OSPF_ALLSPFROUTERS              0xe0000005      /* 224.0.0.5 */
@@ -251,7 +251,6 @@
   int redistribute;                     /* Num of redistributed protocols. */
 
   /* Threads. */
-  struct thread *t_router_lsa_update;   /* router-LSA update timer. */
   struct thread *t_abr_task;            /* ABR task timer. */
   struct thread *t_asbr_check;          /* ASBR check timer. */
   struct thread *t_distribute_update;   /* Distirbute list update timer. */
@@ -261,8 +260,13 @@
 #ifdef HAVE_OPAQUE_LSA
   struct thread *t_opaque_lsa_self;	/* Type-11 Opaque-LSAs origin event. */
 #endif /* HAVE_OPAQUE_LSA */
+
+#define OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT	60
+  unsigned int maxage_delay;		/* Delay on Maxage remover timer, sec */
   struct thread *t_maxage;              /* MaxAge LSA remover timer. */
+#define OSPF_LSA_MAXAGE_CHECK_INTERVAL		30
   struct thread *t_maxage_walker;       /* MaxAge LSA checking timer. */
+
   struct thread *t_deferred_shutdown;	/* deferred/stub-router shutdown timer*/
 
   struct thread *t_write;
@@ -433,7 +437,6 @@
   struct vertex *spf;
 
   /* Threads. */
-  struct thread *t_router_lsa_self;/* Self-originated router-LSA timer. */
   struct thread *t_stub_router;    /* Stub-router timer */
 #ifdef HAVE_OPAQUE_LSA
   struct thread *t_opaque_lsa_self;	/* Type-10 Opaque-LSAs origin. */
diff --git a/ripd/rip_debug.c b/ripd/rip_debug.c
index 64dc27c..662e584 100644
--- a/ripd/rip_debug.c
+++ b/ripd/rip_debug.c
@@ -44,19 +44,16 @@
     {
       if (IS_RIP_DEBUG_SEND && IS_RIP_DEBUG_RECV)
 	{
-	  vty_out (vty, "  RIP packet%s debugging is on%s",
-		   IS_RIP_DEBUG_DETAIL ? " detail" : "",
+	  vty_out (vty, "  RIP packet debugging is on%s",
 		   VTY_NEWLINE);
 	}
       else
 	{
 	  if (IS_RIP_DEBUG_SEND)
-	    vty_out (vty, "  RIP packet send%s debugging is on%s",
-		     IS_RIP_DEBUG_DETAIL ? " detail" : "",
+	    vty_out (vty, "  RIP packet send debugging is on%s",
 		     VTY_NEWLINE);
 	  else
-	    vty_out (vty, "  RIP packet receive%s debugging is on%s",
-		     IS_RIP_DEBUG_DETAIL ? " detail" : "",
+	    vty_out (vty, "  RIP packet receive debugging is on%s",
 		     VTY_NEWLINE);
 	}
     }
@@ -105,11 +102,12 @@
     rip_debug_packet |= RIP_DEBUG_SEND;
   if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
     rip_debug_packet |= RIP_DEBUG_RECV;
-  rip_debug_packet &= ~RIP_DEBUG_DETAIL;
   return CMD_SUCCESS;
 }
 
-DEFUN (debug_rip_packet_detail,
+/* N.B. the "detail" modifier is a no-op.  we leave this command
+   for legacy compatibility. */
+DEFUN_DEPRECATED (debug_rip_packet_detail,
        debug_rip_packet_detail_cmd,
        "debug rip packet (recv|send) detail",
        DEBUG_STR
@@ -124,7 +122,6 @@
     rip_debug_packet |= RIP_DEBUG_SEND;
   if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
     rip_debug_packet |= RIP_DEBUG_RECV;
-  rip_debug_packet |= RIP_DEBUG_DETAIL;
   return CMD_SUCCESS;
 }
 
@@ -224,20 +221,17 @@
     {
       if (IS_RIP_DEBUG_SEND && IS_RIP_DEBUG_RECV)
 	{
-	  vty_out (vty, "debug rip packet%s%s",
-		   IS_RIP_DEBUG_DETAIL ? " detail" : "",
+	  vty_out (vty, "debug rip packet%s",
 		   VTY_NEWLINE);
 	  write++;
 	}
       else
 	{
 	  if (IS_RIP_DEBUG_SEND)
-	    vty_out (vty, "debug rip packet send%s%s",
-		     IS_RIP_DEBUG_DETAIL ? " detail" : "",
+	    vty_out (vty, "debug rip packet send%s",
 		     VTY_NEWLINE);
 	  else
-	    vty_out (vty, "debug rip packet recv%s%s",
-		     IS_RIP_DEBUG_DETAIL ? " detail" : "",
+	    vty_out (vty, "debug rip packet recv%s",
 		     VTY_NEWLINE);
 	  write++;
 	}
diff --git a/ripd/rip_debug.h b/ripd/rip_debug.h
index f3a07ee..990ec90 100644
--- a/ripd/rip_debug.h
+++ b/ripd/rip_debug.h
@@ -40,7 +40,6 @@
 #define IS_RIP_DEBUG_PACKET (rip_debug_packet & RIP_DEBUG_PACKET)
 #define IS_RIP_DEBUG_SEND   (rip_debug_packet & RIP_DEBUG_SEND)
 #define IS_RIP_DEBUG_RECV   (rip_debug_packet & RIP_DEBUG_RECV)
-#define IS_RIP_DEBUG_DETAIL (rip_debug_packet & RIP_DEBUG_DETAIL)
 
 #define IS_RIP_DEBUG_ZEBRA  (rip_debug_zebra & RIP_DEBUG_ZEBRA)
 
diff --git a/ripngd/ripng_debug.c b/ripngd/ripng_debug.c
index 78f13a7..33a7cf6 100644
--- a/ripngd/ripng_debug.c
+++ b/ripngd/ripng_debug.c
@@ -45,19 +45,16 @@
     {
       if (IS_RIPNG_DEBUG_SEND && IS_RIPNG_DEBUG_RECV)
 	{
-	  vty_out (vty, "  RIPng packet%s debugging is on%s",
-		   IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+	  vty_out (vty, "  RIPng packet debugging is on%s",
 		   VTY_NEWLINE);
 	}
       else
 	{
 	  if (IS_RIPNG_DEBUG_SEND)
-	    vty_out (vty, "  RIPng packet send%s debugging is on%s",
-		     IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+	    vty_out (vty, "  RIPng packet send debugging is on%s",
 		     VTY_NEWLINE);
 	  else
-	    vty_out (vty, "  RIPng packet receive%s debugging is on%s",
-		     IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+	    vty_out (vty, "  RIPng packet receive debugging is on%s",
 		     VTY_NEWLINE);
 	}
     }
@@ -106,11 +103,13 @@
     ripng_debug_packet |= RIPNG_DEBUG_SEND;
   if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
     ripng_debug_packet |= RIPNG_DEBUG_RECV;
-  ripng_debug_packet &= ~RIPNG_DEBUG_DETAIL;
+
   return CMD_SUCCESS;
 }
 
-DEFUN (debug_ripng_packet_detail,
+/* N.B. the "detail" modifier is a no-op.  we leave this command
+   for legacy compatibility. */
+DEFUN_DEPRECATED (debug_ripng_packet_detail,
        debug_ripng_packet_detail_cmd,
        "debug ripng packet (recv|send) detail",
        DEBUG_STR
@@ -125,7 +124,7 @@
     ripng_debug_packet |= RIPNG_DEBUG_SEND;
   if (strncmp ("recv", argv[0], strlen (argv[0])) == 0)
     ripng_debug_packet |= RIPNG_DEBUG_RECV;
-  ripng_debug_packet |= RIPNG_DEBUG_DETAIL;
+
   return CMD_SUCCESS;
 }
 
@@ -225,20 +224,17 @@
     {
       if (IS_RIPNG_DEBUG_SEND && IS_RIPNG_DEBUG_RECV)
 	{
-	  vty_out (vty, "debug ripng packet%s%s",
-		   IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+	  vty_out (vty, "debug ripng packet%s",
 		   VTY_NEWLINE);
 	  write++;
 	}
       else
 	{
 	  if (IS_RIPNG_DEBUG_SEND)
-	    vty_out (vty, "debug ripng packet send%s%s",
-		     IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+	    vty_out (vty, "debug ripng packet send%s",
 		     VTY_NEWLINE);
 	  else
-	    vty_out (vty, "debug ripng packet recv%s%s",
-		     IS_RIPNG_DEBUG_DETAIL ? " detail" : "",
+	    vty_out (vty, "debug ripng packet recv%s",
 		     VTY_NEWLINE);
 	  write++;
 	}
diff --git a/ripngd/ripng_debug.h b/ripngd/ripng_debug.h
index f5ed6ea..674345c 100644
--- a/ripngd/ripng_debug.h
+++ b/ripngd/ripng_debug.h
@@ -29,7 +29,6 @@
 #define RIPNG_DEBUG_PACKET  0x01
 #define RIPNG_DEBUG_SEND    0x20
 #define RIPNG_DEBUG_RECV    0x40
-#define RIPNG_DEBUG_DETAIL  0x80
 
 #define RIPNG_DEBUG_ZEBRA   0x01
 
@@ -39,7 +38,6 @@
 #define IS_RIPNG_DEBUG_PACKET (ripng_debug_packet & RIPNG_DEBUG_PACKET)
 #define IS_RIPNG_DEBUG_SEND   (ripng_debug_packet & RIPNG_DEBUG_SEND)
 #define IS_RIPNG_DEBUG_RECV   (ripng_debug_packet & RIPNG_DEBUG_RECV)
-#define IS_RIPNG_DEBUG_DETAIL (ripng_debug_packet & RIPNG_DEBUG_DETAIL)
 
 #define IS_RIPNG_DEBUG_ZEBRA  (ripng_debug_zebra & RIPNG_DEBUG_ZEBRA)
 
diff --git a/tests/aspath_test.c b/tests/aspath_test.c
index fb504f3..9e51e8d 100644
--- a/tests/aspath_test.c
+++ b/tests/aspath_test.c
@@ -649,7 +649,7 @@
       s = stream_new (len);
       stream_put (s, data, len);
     }
-  as = aspath_parse (s, len, use32bit);
+  as = aspath_parse (s, len, use32bit, 0);
   
   if (s)
     stream_free (s);
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 808dcf7..b3111b8 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -642,17 +642,14 @@
 static void *
 route_set_src_compile (const char *arg)
 {
-  sa_family_t family;
   union g_addr src, *psrc;
 
-  if (inet_pton(AF_INET, arg, &src.ipv4) > 0)
-    family = AF_INET;
+  if (inet_pton(AF_INET, arg, &src.ipv4) != 1
 #ifdef HAVE_IPV6
-  else if (inet_pton(AF_INET6, arg, &src.ipv6) > 0)
-    family = AF_INET6;
+      && inet_pton(AF_INET6, arg, &src.ipv6) != 1
 #endif /* HAVE_IPV6 */
-  else
-   return NULL;
+     )
+    return NULL;
 
   psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
   *psrc = src;
diff --git a/zebra/zserv.c b/zebra/zserv.c
index cb5e411..dc3d432 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -451,7 +451,7 @@
     }
 
   /* Metric */
-  if (cmd == ZEBRA_IPV4_ROUTE_ADD || ZEBRA_IPV6_ROUTE_ADD)
+  if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
     {
       SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
       stream_putc (s, rib->distance);