Browse Source

SVN revision 907 from Zebra cvs repository.

hasso 15 years ago
parent
commit
049207c31d

+ 7 - 0
ospf6d/ChangeLog

@@ -1,3 +1,10 @@
+2004-08-01  Yasuhiro Ohara  <yasu@sfc.wide.ad.jp>
+
+	* ospf6_abr.[ch]: add files for abr function.
+	* *.c: VTY_NEWLINE -> VNL
+	* ospf6d.h: version 0.9.7e
+	  show database functions are rewritten.
+
 2004-07-23  Hasso Tepper  <hasso@estpak.ee>
 
 	* ospf6_interface.c, ospf6_zebra.c: use ifp->mtu6 instead of

+ 2 - 2
ospf6d/Makefile.am

@@ -11,13 +11,13 @@ libospf6_a_SOURCES = \
 	ospf6_network.c ospf6_message.c ospf6_lsa.c ospf6_lsdb.c \
 	ospf6_top.c ospf6_area.c ospf6_interface.c ospf6_neighbor.c \
 	ospf6_flood.c ospf6_route.c ospf6_intra.c ospf6_zebra.c \
-	ospf6_spf.c ospf6_proto.c ospf6_asbr.c ospf6d.c
+	ospf6_spf.c ospf6_proto.c ospf6_asbr.c ospf6_abr.c ospf6d.c
 
 noinst_HEADERS = \
 	ospf6_network.h ospf6_message.h ospf6_lsa.h ospf6_lsdb.h \
 	ospf6_top.h ospf6_area.h ospf6_interface.h ospf6_neighbor.h \
 	ospf6_flood.h ospf6_route.h ospf6_intra.h ospf6_zebra.h \
-	ospf6_spf.h ospf6_proto.h ospf6_asbr.h ospf6d.h
+	ospf6_spf.h ospf6_proto.h ospf6_asbr.h ospf6_abr.h ospf6d.h
 
 ospf6d_SOURCES = \
 	ospf6_main.c $(libospf6_a_SOURCES)

+ 426 - 0
ospf6d/ospf6_abr.c

@@ -0,0 +1,426 @@
+/*
+ * Area Border Router function.
+ * Copyright (C) 2004 Yasuhiro Ohara
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING.  If not, write to the 
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
+ * Boston, MA 02111-1307, USA.  
+ */
+
+#include <zebra.h>
+
+#include "log.h"
+#include "prefix.h"
+#include "table.h"
+#include "vty.h"
+#include "linklist.h"
+#include "command.h"
+
+#include "ospf6_proto.h"
+#include "ospf6_route.h"
+#include "ospf6_lsa.h"
+#include "ospf6_route.h"
+#include "ospf6_lsdb.h"
+#include "ospf6_top.h"
+#include "ospf6_area.h"
+#include "ospf6_interface.h"
+#include "ospf6_abr.h"
+#include "ospf6d.h"
+
+unsigned char conf_debug_ospf6_abr;
+
+/* RFC 2328 12.4.3. Summary-LSAs */
+void
+ospf6_abr_originate_prefix_to_area (struct ospf6_route *route,
+                                    struct ospf6_area *area)
+{
+  struct ospf6_lsa *lsa, *old = NULL;
+  struct ospf6_interface *oi;
+  struct ospf6_route *summary, *range = NULL;
+  struct ospf6_area *route_area;
+  char buffer[OSPF6_MAX_LSASIZE];
+  struct ospf6_lsa_header *lsa_header;
+  caddr_t p;
+  struct ospf6_inter_prefix_lsa *prefix_lsa;
+
+  summary = ospf6_route_lookup (&route->prefix, area->summary_table);
+  if (summary)
+    old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTER_PREFIX),
+                             summary->path.origin.id,
+                             area->ospf6->router_id, area->lsdb);
+
+  /* if this route has just removed, remove corresponding LSA */
+  if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
+    {
+      if (old)
+        ospf6_lsa_premature_aging (old);
+      return;
+    }
+
+  /* Only destination type network and address range are considered */
+  if (route->type != OSPF6_DEST_TYPE_NETWORK)
+    {
+      if (old)
+        ospf6_lsa_premature_aging (old);
+      return;
+    }
+
+  /* AS External routes are never considered */
+  if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
+      route->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
+    {
+      if (old)
+        ospf6_lsa_premature_aging (old);
+      return;
+    }
+
+  /* do not generate if the route cost is greater or equal to LSInfinity */
+  if (route->path.cost >= LS_INFINITY)
+    {
+      if (old)
+        ospf6_lsa_premature_aging (old);
+      return;
+    }
+
+  /* if this is an inter-area route */
+  if (route->path.type == OSPF6_PATH_TYPE_INTRA)
+    {
+      /* search for configured address range for the route's area */
+      route_area = ospf6_area_lookup (route->path.area_id, area->ospf6);
+      assert (route_area);
+      range = ospf6_route_lookup_bestmatch (&route->prefix,
+                                            route_area->summary_table);
+    }
+
+  /* ranges are ignored when originate backbone routes to transit area.
+     Otherwise, if ranges are configured, the route is suppressed. */
+  if (range && (route->path.area_id != htonl (0) || ! area->transit_capability))
+    {
+      if (old)
+        ospf6_lsa_premature_aging (old);
+      if (range->path.cost < route->path.cost)
+        range->path.cost = route->path.cost;
+      SET_FLAG (range->flag, OSPF6_ROUTE_HAVE_LONGER);
+      return;
+    }
+
+  /* do not generate if the path's area is the same as target area */
+  if (route->path.area_id == area->area_id)
+    {
+      if (old)
+        ospf6_lsa_premature_aging (old);
+      return;
+    }
+
+  /* do not generate if the nexthops belongs to the target area */
+  oi = ospf6_interface_lookup_by_ifindex (route->nexthop[0].ifindex);
+  if (oi && oi->area && oi->area->area_id == area->area_id)
+    {
+      if (old)
+        ospf6_lsa_premature_aging (old);
+      return;
+    }
+
+  /* the route is going to be originated. store it in area's summary_table */
+  if (summary == NULL)
+    {
+      summary = ospf6_route_copy (route);
+      summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_PREFIX);
+      summary->path.origin.adv_router = area->ospf6->router_id;
+      summary->path.origin.id =
+        ospf6_new_ls_id (summary->path.origin.type,
+                         summary->path.origin.adv_router, area->lsdb);
+      ospf6_route_add (summary, area->summary_table);
+    }
+
+  /* prepare buffer */
+  memset (buffer, 0, sizeof (buffer));
+  lsa_header = (struct ospf6_lsa_header *) buffer;
+  prefix_lsa = (struct ospf6_inter_prefix_lsa *)
+    ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
+  p = (caddr_t) prefix_lsa + sizeof (struct ospf6_inter_prefix_lsa);
+
+  /* Fill Inter-Area-Prefix-LSA */
+  OSPF6_ABR_SUMMARY_METRIC_SET (prefix_lsa, route->path.cost);
+
+  /* prefixlen */
+  prefix_lsa->prefix.prefix_length = route->prefix.prefixlen;
+
+  /* PrefixOptions */
+  prefix_lsa->prefix.prefix_options = route->path.prefix_options;
+
+  /* set Prefix */
+  memcpy (p, &route->prefix.u.prefix6,
+          OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
+  ospf6_prefix_apply_mask (&prefix_lsa->prefix);
+  p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
+
+  /* Fill LSA Header */
+  lsa_header->age = 0;
+  lsa_header->type = htons (OSPF6_LSTYPE_INTER_PREFIX);
+  lsa_header->id = summary->path.origin.id;
+  lsa_header->adv_router = area->ospf6->router_id;
+  lsa_header->seqnum =
+    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
+                         lsa_header->adv_router, area->lsdb);
+  lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
+
+  /* LSA checksum */
+  ospf6_lsa_checksum (lsa_header);
+
+  /* create LSA */
+  lsa = ospf6_lsa_create (lsa_header);
+  lsa->scope = area;
+  SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH); /* XXX */
+
+  /* Originate */
+  ospf6_lsa_originate (lsa);
+}
+
+void
+ospf6_abr_originate_prefix (struct ospf6_route *route, struct ospf6 *o)
+{
+  listnode node;
+  struct ospf6_area *oa;
+
+  for (node = listhead (o->area_list); node; nextnode (node))
+    {
+      oa = (struct ospf6_area *) getdata (node);
+      ospf6_abr_originate_prefix_to_area (route, oa);
+    }
+}
+
+/* RFC 2328 16.2. Calculating the inter-area routes */
+void
+ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa)
+{
+  struct prefix prefix, abr_prefix;
+  struct ospf6_route_table *table = NULL;
+  struct ospf6_route *range, *route, *old = NULL;
+  struct ospf6_route *abr_entry;
+  u_char type;
+  char options[3] = {0, 0, 0};
+  u_int8_t prefix_options = 0;
+  u_int32_t cost = 0;
+  int i;
+
+  if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_PREFIX))
+    {
+      struct ospf6_inter_prefix_lsa *prefix_lsa;
+      prefix_lsa = (struct ospf6_inter_prefix_lsa *)
+        OSPF6_LSA_HEADER_END (lsa->header);
+      prefix.family = AF_INET6;
+      prefix.prefixlen = prefix_lsa->prefix.prefix_length;
+      ospf6_prefix_in6_addr (&prefix.u.prefix6, &prefix_lsa->prefix);
+      table = oa->ospf6->route_table;
+      type = OSPF6_DEST_TYPE_NETWORK;
+      prefix_options = prefix_lsa->prefix.prefix_options;
+      cost = OSPF6_ABR_SUMMARY_METRIC (prefix_lsa);
+    }
+  else if (lsa->header->type == htons (OSPF6_LSTYPE_INTER_ROUTER))
+    {
+      struct ospf6_inter_router_lsa *router_lsa;
+      router_lsa = (struct ospf6_inter_router_lsa *)
+        OSPF6_LSA_HEADER_END (lsa->header);
+      ospf6_linkstate_prefix (router_lsa->router_id, htonl (0), &prefix);
+      table = oa->ospf6->brouter_table;
+      type = OSPF6_DEST_TYPE_ROUTER;
+      options[0] = router_lsa->options[0];
+      options[1] = router_lsa->options[1];
+      options[2] = router_lsa->options[2];
+      cost = OSPF6_ABR_SUMMARY_METRIC (router_lsa);
+    }
+  else
+    assert (0);
+
+  for (route = ospf6_route_lookup (&prefix, table);
+       route && ospf6_route_is_prefix (&prefix, route);
+       route = ospf6_route_next (route))
+    {
+      if (route->path.area_id == oa->area_id &&
+          route->path.origin.type == lsa->header->type &&
+          route->path.origin.id == lsa->header->id &&
+          route->path.origin.adv_router == lsa->header->adv_router)
+        old = route;
+    }
+
+  /* (1) if cost == LSInfinity or if the LSA is MaxAge */
+  if (cost == LS_INFINITY || OSPF6_LSA_IS_MAXAGE (lsa))
+    {
+      if (old)
+        ospf6_route_remove (old, oa->ospf6->route_table);
+      return;
+    }
+
+  /* (2) if the LSA is self-originated, ignore */
+  if (lsa->header->adv_router == oa->ospf6->router_id)
+    {
+      if (old)
+        ospf6_route_remove (old, oa->ospf6->route_table);
+      return;
+    }
+
+  /* (3) if the prefix is equal to an active configured address range */
+  range = ospf6_route_lookup (&prefix, oa->summary_table);
+  if (range && CHECK_FLAG (range->flag, OSPF6_ROUTE_HAVE_LONGER))
+    {
+      if (old)
+        ospf6_route_remove (old, oa->ospf6->route_table);
+      return;
+    }
+
+  /* (4) if the routing table entry for the ABR does not exist */
+  ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &abr_prefix);
+  abr_entry = ospf6_route_lookup (&abr_prefix, oa->ospf6->brouter_table);
+  if (abr_entry == NULL)
+    {
+      if (old)
+        ospf6_route_remove (old, oa->ospf6->route_table);
+      return;
+    }
+
+  /* (5),(6),(7) the path preference is handled by the sorting
+     in the routing table. Always install the path by substituting
+     old route (if any). */
+  if (old)
+    route = old;
+  else
+    route = ospf6_route_create ();
+
+  route->type = type;
+  route->prefix = prefix;
+  route->path.origin.type = lsa->header->type;
+  route->path.origin.id = lsa->header->id;
+  route->path.origin.adv_router = lsa->header->adv_router;
+  route->path.options[0] = options[0];
+  route->path.options[1] = options[1];
+  route->path.options[2] = options[2];
+  route->path.prefix_options = prefix_options;
+  route->path.area_id = oa->area_id;
+  route->path.type = OSPF6_PATH_TYPE_INTER;
+  route->path.cost = abr_entry->path.cost + cost;
+  for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
+    route->nexthop[i] = abr_entry->nexthop[i];
+
+  ospf6_route_add (route, table);
+}
+
+int
+dummy (struct ospf6_lsa *lsa)
+{
+}
+
+
+/* Display functions */
+int
+ospf6_inter_area_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
+{
+  struct ospf6_inter_prefix_lsa *prefix_lsa;
+  struct in6_addr in6;
+  char buf[64];
+
+  prefix_lsa = (struct ospf6_inter_prefix_lsa *)
+    OSPF6_LSA_HEADER_END (lsa->header);
+
+  vty_out (vty, "     Metric: %lu%s",
+           (u_long) OSPF6_ABR_SUMMARY_METRIC (prefix_lsa), VNL);
+
+  ospf6_prefix_options_printbuf (prefix_lsa->prefix.prefix_options,
+                                 buf, sizeof (buf));
+  vty_out (vty, "     Prefix Options: %s%s", buf, VNL);
+
+  ospf6_prefix_in6_addr (&in6, &prefix_lsa->prefix);
+  inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
+  vty_out (vty, "     Prefix: %s/%d%s", buf,
+           prefix_lsa->prefix.prefix_length, VNL);
+
+  return 0;
+}
+
+int
+ospf6_inter_area_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
+{
+  struct ospf6_inter_router_lsa *router_lsa;
+  char buf[64];
+
+  router_lsa = (struct ospf6_inter_router_lsa *)
+    OSPF6_LSA_HEADER_END (lsa->header);
+
+  ospf6_options_printbuf (router_lsa->options, buf, sizeof (buf));
+  vty_out (vty, "     Options: %s%s", buf, VNL);
+  vty_out (vty, "     Metric: %lu%s",
+           (u_long) OSPF6_ABR_SUMMARY_METRIC (router_lsa), VNL);
+  inet_ntop (AF_INET, &router_lsa->router_id, buf, sizeof (buf));
+  vty_out (vty, "     Destination Router ID: %s%s", buf, VNL);
+
+  return 0;
+}
+
+/* Debug commands */
+DEFUN (debug_ospf6_abr,
+       debug_ospf6_abr_cmd,
+       "debug ospf6 abr",
+       DEBUG_STR
+       OSPF6_STR
+       "Debug OSPFv3 ABR function\n"
+      )
+{
+  OSPF6_DEBUG_ABR_ON ();
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_ospf6_abr,
+       no_debug_ospf6_abr_cmd,
+       "no debug ospf6 abr",
+       NO_STR
+       DEBUG_STR
+       OSPF6_STR
+       "Debug OSPFv3 ABR function\n"
+      )
+{
+  OSPF6_DEBUG_ABR_OFF ();
+  return CMD_SUCCESS;
+}
+
+int
+config_write_ospf6_debug_abr (struct vty *vty)
+{
+  if (IS_OSPF6_DEBUG_ABR)
+    vty_out (vty, "debug ospf6 abr%s", VNL);
+  return 0;
+}
+
+void
+install_element_ospf6_debug_abr ()
+{
+  install_element (ENABLE_NODE, &debug_ospf6_abr_cmd);
+  install_element (ENABLE_NODE, &no_debug_ospf6_abr_cmd);
+  install_element (CONFIG_NODE, &debug_ospf6_abr_cmd);
+  install_element (CONFIG_NODE, &no_debug_ospf6_abr_cmd);
+}
+
+void
+ospf6_abr_init ()
+{
+  ospf6_lstype[3].name = "Inter-Area-Prefix-LSA";
+  ospf6_lstype[3].reoriginate = dummy;
+  ospf6_lstype[3].show = ospf6_inter_area_prefix_lsa_show;
+  ospf6_lstype[4].name = "Inter-Area-Router-LSA";
+  ospf6_lstype[4].reoriginate = dummy;
+  ospf6_lstype[4].show = ospf6_inter_area_router_lsa_show;
+}
+
+

+ 68 - 0
ospf6d/ospf6_abr.h

@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004 Yasuhiro Ohara
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING.  If not, write to the 
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
+ * Boston, MA 02111-1307, USA.  
+ */
+
+#ifndef OSPF6_ABR_H
+#define OSPF6_ABR_H
+
+/* Debug option */
+extern unsigned char conf_debug_ospf6_abr;
+#define OSPF6_DEBUG_ABR_ON() \
+  (conf_debug_ospf6_abr = 1)
+#define OSPF6_DEBUG_ABR_OFF() \
+  (conf_debug_ospf6_abr = 0)
+#define IS_OSPF6_DEBUG_ABR \
+  (conf_debug_ospf6_abr)
+
+/* Inter-Area-Prefix-LSA */
+struct ospf6_inter_prefix_lsa
+{
+  u_int32_t metric;
+  struct ospf6_prefix prefix;
+};
+
+/* Inter-Area-Router-LSA */
+struct ospf6_inter_router_lsa
+{
+  u_char mbz;
+  u_char options[3];
+  u_int32_t metric;
+  u_int32_t router_id;
+};
+
+#define OSPF6_ABR_SUMMARY_METRIC(E) (ntohl ((E)->metric & htonl (0x00ffffff)))
+#define OSPF6_ABR_SUMMARY_METRIC_SET(E,C) \
+  { (E)->metric &= htonl (0x00000000); \
+    (E)->metric |= htonl (0x00ffffff) & htonl (C); }
+
+void ospf6_abr_originate_prefix_to_area (struct ospf6_route *route,
+                                         struct ospf6_area *area);
+void ospf6_abr_originate_prefix (struct ospf6_route *route, struct ospf6 *o);
+void ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa);
+
+int config_write_ospf6_debug_abr (struct vty *vty);
+void install_element_ospf6_debug_abr ();
+int ospf6_abr_config_write (struct vty *vty);
+
+void ospf6_abr_init ();
+
+#endif /*OSPF6_ABR_H*/
+
+

+ 41 - 29
ospf6d/ospf6_area.c

@@ -31,7 +31,6 @@
 #include "prefix.h"
 #include "table.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
@@ -41,6 +40,8 @@
 #include "ospf6_area.h"
 #include "ospf6_interface.h"
 #include "ospf6_intra.h"
+#include "ospf6_abr.h"
+#include "ospf6d.h"
 
 int
 ospf6_area_cmp (void *va, void *vb)
@@ -137,6 +138,7 @@ struct ospf6_area *
 ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
 {
   struct ospf6_area *oa;
+  struct ospf6_route *route;
 
   oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
 
@@ -144,6 +146,8 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
   oa->area_id = area_id;
   oa->if_list = list_new ();
 
+  oa->summary_table = ospf6_route_table_create ();
+
   oa->lsdb = ospf6_lsdb_create ();
   oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
   oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
@@ -161,6 +165,11 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
   oa->ospf6 = o;
   listnode_add_sort (o->area_list, oa);
 
+  /* import athoer area's routes as inter-area routes */
+  for (route = ospf6_route_head (o->route_table); route;
+       route = ospf6_route_next (route))
+    ospf6_abr_originate_prefix_to_area (route, oa);
+
   return oa;
 }
 
@@ -170,6 +179,8 @@ ospf6_area_delete (struct ospf6_area *oa)
   listnode n;
   struct ospf6_interface *oi;
 
+  ospf6_route_table_delete (oa->summary_table);
+
   /* ospf6 interface list */
   for (n = listhead (oa->if_list); n; nextnode (n))
     {
@@ -250,9 +261,9 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
   listnode i;
   struct ospf6_interface *oi;
 
-  vty_out (vty, " Area %s%s", oa->name, VTY_NEWLINE);
+  vty_out (vty, " Area %s%s", oa->name, VNL);
   vty_out (vty, "     Number of Area scoped LSAs is %u%s",
-           oa->lsdb->count, VTY_NEWLINE);
+           oa->lsdb->count, VNL);
 
   vty_out (vty, "     Interface attached to this area:");
   for (i = listhead (oa->if_list); i; nextnode (i))
@@ -260,24 +271,24 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
       oi = (struct ospf6_interface *) getdata (i);
       vty_out (vty, " %s", oi->interface->name);
     }
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, "%s", VNL);
 }
 
 
-#define OSPF6_CMD_AREA_LOOKUP(str, oa)                             \
-{                                                                  \
-  u_int32_t area_id = 0;                                           \
-  if (inet_pton (AF_INET, str, &area_id) != 1)                     \
-    {                                                              \
-      vty_out (vty, "Malformed Area-ID: %s%s", str, VTY_NEWLINE);  \
-      return CMD_SUCCESS;                                          \
-    }                                                              \
-  oa = ospf6_area_lookup (area_id, ospf6);                         \
-  if (oa == NULL)                                                  \
-    {                                                              \
-      vty_out (vty, "No such Area: %s%s", str, VTY_NEWLINE);       \
-      return CMD_SUCCESS;                                          \
-    }                                                              \
+#define OSPF6_CMD_AREA_LOOKUP(str, oa)                     \
+{                                                          \
+  u_int32_t area_id = 0;                                   \
+  if (inet_pton (AF_INET, str, &area_id) != 1)             \
+    {                                                      \
+      vty_out (vty, "Malformed Area-ID: %s%s", str, VNL);  \
+      return CMD_SUCCESS;                                  \
+    }                                                      \
+  oa = ospf6_area_lookup (area_id, ospf6);                 \
+  if (oa == NULL)                                          \
+    {                                                      \
+      vty_out (vty, "No such Area: %s%s", str, VNL);       \
+      return CMD_SUCCESS;                                  \
+    }                                                      \
 }
 
 DEFUN (show_ipv6_ospf6_area_route_intra,
@@ -396,7 +407,7 @@ DEFUN (show_ipv6_ospf6_route_intra,
   for (node = listhead (ospf6->area_list); node; nextnode (node))
     {
       oa = (struct ospf6_area *) getdata (node);
-      vty_out (vty, "Area %s%s", oa->name, VTY_NEWLINE);
+      vty_out (vty, "Area %s%s", oa->name, VNL);
       ospf6_route_table_show (vty, argc, argv, oa->route_table);
     }
 
@@ -508,7 +519,7 @@ DEFUN (show_ipv6_ospf6_spf_tree,
       if (route == NULL)
         {
           vty_out (vty, "LS entry for root not found in area %s%s",
-                   oa->name, VTY_NEWLINE);
+                   oa->name, VNL);
           continue;
         }
       root = (struct ospf6_vertex *) route->route_option;
@@ -539,13 +550,13 @@ DEFUN (show_ipv6_ospf6_area_spf_tree,
 
   if (inet_pton (AF_INET, argv[0], &area_id) != 1)
     {
-      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
       return CMD_SUCCESS;
     }
   oa = ospf6_area_lookup (area_id, ospf6);
   if (oa == NULL)
     {
-      vty_out (vty, "No such Area: %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "No such Area: %s%s", argv[0], VNL);
       return CMD_SUCCESS;
     }
 
@@ -553,7 +564,7 @@ DEFUN (show_ipv6_ospf6_area_spf_tree,
   if (route == NULL)
     {
       vty_out (vty, "LS entry for root not found in area %s%s",
-               oa->name, VTY_NEWLINE);
+               oa->name, VNL);
       return CMD_SUCCESS;
     }
   root = (struct ospf6_vertex *) route->route_option;
@@ -579,13 +590,13 @@ DEFUN (show_ipv6_ospf6_area_spf_table,
 
   if (inet_pton (AF_INET, argv[0], &area_id) != 1)
     {
-      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
       return CMD_SUCCESS;
     }
   oa = ospf6_area_lookup (area_id, ospf6);
   if (oa == NULL)
     {
-      vty_out (vty, "No such Area: %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "No such Area: %s%s", argv[0], VNL);
       return CMD_SUCCESS;
     }
 
@@ -651,13 +662,13 @@ DEFUN (show_ipv6_ospf6_area_spf_table_3,
 
   if (inet_pton (AF_INET, argv[0], &area_id) != 1)
     {
-      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
       return CMD_SUCCESS;
     }
   oa = ospf6_area_lookup (area_id, ospf6);
   if (oa == NULL)
     {
-      vty_out (vty, "No such Area: %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "No such Area: %s%s", argv[0], VNL);
       return CMD_SUCCESS;
     }
 
@@ -785,13 +796,13 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
 
   if (inet_pton (AF_INET, argv[1], &area_id) != 1)
     {
-      vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VTY_NEWLINE);
+      vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VNL);
       return CMD_SUCCESS;
     }
   oa = ospf6_area_lookup (area_id, ospf6);
   if (oa == NULL)
     {
-      vty_out (vty, "No such Area: %s%s", argv[1], VTY_NEWLINE);
+      vty_out (vty, "No such Area: %s%s", argv[1], VNL);
       return CMD_SUCCESS;
     }
 
@@ -866,3 +877,4 @@ ospf6_area_init ()
 
   install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
 }
+

+ 6 - 0
ospf6d/ospf6_area.h

@@ -41,6 +41,12 @@ struct ospf6_area
   /* OSPF Option */
   u_char options[3];
 
+  /* TransitCapability */
+  int transit_capability;
+
+  /* Summary routes to be originated (includes Configured Address Ranges) */
+  struct ospf6_route_table *summary_table;
+
   /* OSPF interface list */
   list if_list;
 

+ 20 - 20
ospf6d/ospf6_asbr.c

@@ -32,7 +32,6 @@
 #include "thread.h"
 #include "linklist.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
@@ -42,6 +41,7 @@
 #include "ospf6_area.h"
 #include "ospf6_asbr.h"
 #include "ospf6_intra.h"
+#include "ospf6d.h"
 
 unsigned char conf_debug_ospf6_asbr = 0;
 
@@ -144,8 +144,8 @@ ospf6_as_external_lsa_originate_sub (struct ospf6_route *route, int force)
   lsa_header->id = htonl (info->id);
   lsa_header->adv_router = ospf6->router_id;
   lsa_header->seqnum =
-    ospf6_lsa_new_seqnum (lsa_header->type, lsa_header->id,
-                          lsa_header->adv_router, ospf6);
+    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
+                         lsa_header->adv_router, ospf6->lsdb);
   lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
 
   /* LSA checksum */
@@ -778,10 +778,10 @@ ospf6_redistribute_config_write (struct vty *vty)
 
       if (ospf6->rmap[type].name)
         vty_out (vty, " redistribute %s route-map %s%s",
-                 ZROUTE_NAME (type), ospf6->rmap[type].name, VTY_NEWLINE);
+                 ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
       else
         vty_out (vty, " redistribute %s%s",
-                 ZROUTE_NAME (type), VTY_NEWLINE);
+                 ZROUTE_NAME (type), VNL);
     }
 
   return 0;
@@ -807,7 +807,7 @@ ospf6_redistribute_show_config (struct vty *vty)
       total++;
     }
 
-  vty_out (vty, "Redistributing External Routes from:%s", VTY_NEWLINE);
+  vty_out (vty, "Redistributing External Routes from:%s", VNL);
   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
     {
       if (type == ZEBRA_ROUTE_OSPF6)
@@ -819,12 +819,12 @@ ospf6_redistribute_show_config (struct vty *vty)
         vty_out (vty, "    %d: %s with route-map \"%s\"%s%s", nroute[type],
                  ZROUTE_NAME (type), ospf6->rmap[type].name,
                  (ospf6->rmap[type].map ? "" : " (not found !)"),
-                 VTY_NEWLINE);
+                 VNL);
       else
         vty_out (vty, "    %d: %s%s", nroute[type],
-                 ZROUTE_NAME (type), VTY_NEWLINE);
+                 ZROUTE_NAME (type), VNL);
     }
-  vty_out (vty, "Total %d routes%s", total, VTY_NEWLINE);
+  vty_out (vty, "Total %d routes%s", total, VNL);
 }
 
 
@@ -1004,13 +1004,13 @@ route_map_command_status (struct vty *vty, int ret)
   switch (ret)
     {
     case RMAP_RULE_MISSING:
-      vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
+      vty_out (vty, "Can't find rule.%s", VNL);
       break;
     case RMAP_COMPILE_ERROR:
-      vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
+      vty_out (vty, "Argument is malformed.%s", VNL);
       break;
     default:
-      vty_out (vty, "route-map add set failed.%s", VTY_NEWLINE);
+      vty_out (vty, "route-map add set failed.%s", VNL);
       break;
     }
   return CMD_WARNING;
@@ -1179,23 +1179,23 @@ ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
 
-  vty_out (vty, "     Bits: %s%s", buf, VTY_NEWLINE);
+  vty_out (vty, "     Bits: %s%s", buf, VNL);
   vty_out (vty, "     Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
-           VTY_NEWLINE);
+           VNL);
 
   ospf6_prefix_options_printbuf (external->prefix.prefix_options,
                                  buf, sizeof (buf));
   vty_out (vty, "     Prefix Options: %s%s", buf,
-           VTY_NEWLINE);
+           VNL);
 
   vty_out (vty, "     Referenced LSType: %d%s",
            ntohs (external->prefix.prefix_refer_lstype),
-           VTY_NEWLINE);
+           VNL);
 
   ospf6_prefix_in6_addr (&in6, &external->prefix);
   inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
   vty_out (vty, "     Prefix: %s/%d%s", buf,
-           external->prefix.prefix_length, VTY_NEWLINE);
+           external->prefix.prefix_length, VNL);
 
   /* Forwarding-Address */
   if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
@@ -1204,7 +1204,7 @@ ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
         ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
          OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
       inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
-      vty_out (vty, "     Forwarding-Address: %s%s", buf, VTY_NEWLINE);
+      vty_out (vty, "     Forwarding-Address: %s%s", buf, VNL);
     }
 
   return 0;
@@ -1231,7 +1231,7 @@ ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
            prefix, id, route->path.metric_type,
            (u_long) (route->path.metric_type == 2 ?
                      route->path.cost_e2 : route->path.cost),
-           forwarding, VTY_NEWLINE);
+           forwarding, VNL);
 }
 
 DEFUN (show_ipv6_ospf6_redistribute,
@@ -1378,7 +1378,7 @@ int
 config_write_ospf6_debug_asbr (struct vty *vty)
 {
   if (IS_OSPF6_DEBUG_ASBR)
-    vty_out (vty, "debug ospf6 asbr%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 asbr%s", VNL);
   return 0;
 }
 

+ 89 - 39
ospf6d/ospf6_interface.c

@@ -29,7 +29,6 @@
 #include "prefix.h"
 #include "plist.h"
 
-#include "ospf6d.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
 #include "ospf6_network.h"
@@ -41,6 +40,7 @@
 #include "ospf6_neighbor.h"
 #include "ospf6_intra.h"
 #include "ospf6_spf.h"
+#include "ospf6d.h"
 
 unsigned char conf_debug_ospf6_interface = 0;
 
@@ -785,18 +785,18 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
 
   vty_out (vty, "%s is %s, type %s%s",
            ifp->name, updown[if_is_up (ifp)], type,
-	   VTY_NEWLINE);
-  vty_out (vty, "  Interface ID: %d%s", ifp->ifindex, VTY_NEWLINE);
+	   VNL);
+  vty_out (vty, "  Interface ID: %d%s", ifp->ifindex, VNL);
 
   if (ifp->info == NULL)
     {
-      vty_out (vty, "   OSPF not enabled on this interface%s", VTY_NEWLINE);
+      vty_out (vty, "   OSPF not enabled on this interface%s", VNL);
       return 0;
     }
   else
     oi = (struct ospf6_interface *) ifp->info;
 
-  vty_out (vty, "  Internet Address:%s", VTY_NEWLINE);
+  vty_out (vty, "  Internet Address:%s", VNL);
   for (i = listhead (ifp->connected); i; nextnode (i))
     {
       c = (struct connected *)getdata (i);
@@ -806,15 +806,15 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
         {
         case AF_INET:
           vty_out (vty, "    inet : %s%s", strbuf,
-		   VTY_NEWLINE);
+		   VNL);
           break;
         case AF_INET6:
           vty_out (vty, "    inet6: %s%s", strbuf,
-		   VTY_NEWLINE);
+		   VNL);
           break;
         default:
           vty_out (vty, "    ???  : %s%s", strbuf,
-		   VTY_NEWLINE);
+		   VNL);
           break;
         }
     }
@@ -822,30 +822,30 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
   if (oi->area)
     {
       vty_out (vty, "  Instance ID %d, Interface MTU %d (autodetect: %d)%s",
-	       oi->instance_id, oi->ifmtu, ifp->mtu6, VTY_NEWLINE);
+	       oi->instance_id, oi->ifmtu, ifp->mtu6, VNL);
       inet_ntop (AF_INET, &oi->area->area_id,
                  strbuf, sizeof (strbuf));
       vty_out (vty, "  Area ID %s, Cost %hu%s", strbuf, oi->cost,
-	       VTY_NEWLINE);
+	       VNL);
     }
   else
-    vty_out (vty, "  Not Attached to Area%s", VTY_NEWLINE);
+    vty_out (vty, "  Not Attached to Area%s", VNL);
 
   vty_out (vty, "  State %s, Transmit Delay %d sec, Priority %d%s",
            ospf6_interface_state_str[oi->state],
            oi->transdelay, oi->priority,
-	   VTY_NEWLINE);
-  vty_out (vty, "  Timer intervals configured:%s", VTY_NEWLINE);
+	   VNL);
+  vty_out (vty, "  Timer intervals configured:%s", VNL);
   vty_out (vty, "   Hello %d, Dead %d, Retransmit %d%s",
            oi->hello_interval, oi->dead_interval, oi->rxmt_interval,
-	   VTY_NEWLINE);
+	   VNL);
 
   inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter));
   inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter));
-  vty_out (vty, "  DR: %s BDR: %s%s", drouter, bdrouter, VTY_NEWLINE);
+  vty_out (vty, "  DR: %s BDR: %s%s", drouter, bdrouter, VNL);
 
   vty_out (vty, "  Number of I/F scoped LSAs is %u%s",
-           oi->lsdb->count, VTY_NEWLINE);
+           oi->lsdb->count, VNL);
 
   gettimeofday (&now, (struct timezone *) NULL);
 
@@ -856,10 +856,10 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
   vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
            oi->lsupdate_list->count, duration,
            (oi->thread_send_lsupdate ? "on" : "off"),
-           VTY_NEWLINE);
+           VNL);
   for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
-    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);
+    vty_out (vty, "      %s%s", lsa->name, VNL);
 
   timerclear (&res);
   if (oi->thread_send_lsack)
@@ -868,10 +868,10 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
   vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
            oi->lsack_list->count, duration,
            (oi->thread_send_lsack ? "on" : "off"),
-           VTY_NEWLINE);
+           VNL);
   for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
-    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);
+    vty_out (vty, "      %s%s", lsa->name, VNL);
 
   return 0;
 }
@@ -896,7 +896,7 @@ DEFUN (show_ipv6_ospf6_interface,
       if (ifp == NULL)
         {
           vty_out (vty, "No such Interface: %s%s", argv[0],
-                   VTY_NEWLINE);
+                   VNL);
           return CMD_WARNING;
         }
       ospf6_interface_show (vty, ifp);
@@ -939,14 +939,14 @@ DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
   ifp = if_lookup_by_name (argv[0]);
   if (ifp == NULL)
     {
-      vty_out (vty, "No such Interface: %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "No such Interface: %s%s", argv[0], VNL);
       return CMD_WARNING;
     }
 
   oi = ifp->info;
   if (oi == NULL)
     {
-      vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[0], VNL);
       return CMD_WARNING;
     }
 
@@ -1071,7 +1071,7 @@ DEFUN (ipv6_ospf6_ifmtu,
   if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu)
     {
       vty_out (vty, "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)%s",
-               ifp->name, ifp->mtu6, VTY_NEWLINE);
+               ifp->name, ifp->mtu6, VNL);
       return CMD_WARNING;
     }
 
@@ -1081,7 +1081,7 @@ DEFUN (ipv6_ospf6_ifmtu,
       if (iobuflen < ifmtu)
         {
           vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
-                   ifp->name, iobuflen, VTY_NEWLINE);
+                   ifp->name, iobuflen, VNL);
           oi->ifmtu = iobuflen;
         }
       else
@@ -1101,6 +1101,55 @@ DEFUN (ipv6_ospf6_ifmtu,
   return CMD_SUCCESS;
 }
 
+DEFUN (no_ipv6_ospf6_ifmtu,
+       no_ipv6_ospf6_ifmtu_cmd,
+       "no ipv6 ospf6 ifmtu",
+       NO_STR
+       IP6_STR
+       OSPF6_STR
+       "Interface MTU\n"
+       )
+{
+  struct ospf6_interface *oi;
+  struct interface *ifp;
+  int iobuflen;
+  listnode node;
+  struct ospf6_neighbor *on;
+
+  ifp = (struct interface *) vty->index;
+  assert (ifp);
+
+  oi = (struct ospf6_interface *) ifp->info;
+  if (oi == NULL)
+    oi = ospf6_interface_create (ifp);
+  assert (oi);
+
+  if (oi->ifmtu < ifp->mtu)
+    {
+      iobuflen = ospf6_iobuf_size (ifp->mtu);
+      if (iobuflen < ifp->mtu)
+        {
+          vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
+                   ifp->name, iobuflen, VNL);
+          oi->ifmtu = iobuflen;
+        }
+      else
+        oi->ifmtu = ifp->mtu;
+    }
+  else
+    oi->ifmtu = ifp->mtu;
+
+  /* re-establish adjacencies */
+  for (node = listhead (oi->neighbor_list); node; nextnode (node))
+    {
+      on = (struct ospf6_neighbor *) getdata (node);
+      THREAD_OFF (on->inactivity_timer);
+      thread_execute (master, inactivity_timer, on, 0);
+    }
+
+  return CMD_SUCCESS;
+}
+
 DEFUN (ipv6_ospf6_cost,
        ipv6_ospf6_cost_cmd,
        "ipv6 ospf6 cost <1-65535>",
@@ -1447,36 +1496,36 @@ config_write_ospf6_interface (struct vty *vty)
         continue;
 
       vty_out (vty, "interface %s%s",
-               oi->interface->name, VTY_NEWLINE);
+               oi->interface->name, VNL);
 
       if (ifp->desc)
-        vty_out (vty, " description %s%s", ifp->desc, VTY_NEWLINE);
+        vty_out (vty, " description %s%s", ifp->desc, VNL);
 
       if (ifp->mtu6 != oi->ifmtu)
-        vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VTY_NEWLINE);
+        vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VNL);
       vty_out (vty, " ipv6 ospf6 cost %d%s",
-               oi->cost, VTY_NEWLINE);
+               oi->cost, VNL);
       vty_out (vty, " ipv6 ospf6 hello-interval %d%s",
-               oi->hello_interval, VTY_NEWLINE);
+               oi->hello_interval, VNL);
       vty_out (vty, " ipv6 ospf6 dead-interval %d%s",
-               oi->dead_interval, VTY_NEWLINE);
+               oi->dead_interval, VNL);
       vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s",
-               oi->rxmt_interval, VTY_NEWLINE);
+               oi->rxmt_interval, VNL);
       vty_out (vty, " ipv6 ospf6 priority %d%s",
-               oi->priority, VTY_NEWLINE);
+               oi->priority, VNL);
       vty_out (vty, " ipv6 ospf6 transmit-delay %d%s",
-               oi->transdelay, VTY_NEWLINE);
+               oi->transdelay, VNL);
       vty_out (vty, " ipv6 ospf6 instance-id %d%s",
-               oi->instance_id, VTY_NEWLINE);
+               oi->instance_id, VNL);
 
       if (oi->plist_name)
         vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s",
-                 oi->plist_name, VTY_NEWLINE);
+                 oi->plist_name, VNL);
 
       if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
-        vty_out (vty, " ipv6 ospf6 passive%s", VTY_NEWLINE);
+        vty_out (vty, " ipv6 ospf6 passive%s", VNL);
 
-      vty_out (vty, "!%s", VTY_NEWLINE);
+      vty_out (vty, "!%s", VNL);
     }
   return 0;
 }
@@ -1516,6 +1565,7 @@ ospf6_interface_init ()
   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
   install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
   install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
+  install_element (INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
   install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
   install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
   install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
@@ -1559,7 +1609,7 @@ int
 config_write_ospf6_debug_interface (struct vty *vty)
 {
   if (IS_OSPF6_DEBUG_INTERFACE)
-    vty_out (vty, "debug ospf6 interface%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 interface%s", VNL);
   return 0;
 }
 

+ 29 - 29
ospf6d/ospf6_intra.c

@@ -31,7 +31,6 @@
 #include "vty.h"
 #include "command.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_message.h"
 #include "ospf6_route.h"
@@ -44,6 +43,7 @@
 #include "ospf6_neighbor.h"
 #include "ospf6_intra.h"
 #include "ospf6_asbr.h"
+#include "ospf6d.h"
 
 /******************************/
 /* RFC2740 3.4.3.1 Router-LSA */
@@ -62,7 +62,7 @@ ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
 
   ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits));
   ospf6_options_printbuf (router_lsa->options, options, sizeof (options));
-  vty_out (vty, "    Bits: %s Options: %s%s", bits, options, VTY_NEWLINE);
+  vty_out (vty, "    Bits: %s Options: %s%s", bits, options, VNL);
 
   start = (char *) router_lsa + sizeof (struct ospf6_router_lsa);
   end = (char *) lsa->header + ntohs (lsa->header->length);
@@ -83,16 +83,16 @@ ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
         snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
 
       vty_out (vty, "    Type: %s Metric: %d%s",
-               name, ntohs (lsdesc->metric), VTY_NEWLINE);
+               name, ntohs (lsdesc->metric), VNL);
       vty_out (vty, "    Interface ID: %s%s",
                inet_ntop (AF_INET, &lsdesc->interface_id,
-                          buf, sizeof (buf)), VTY_NEWLINE);
+                          buf, sizeof (buf)), VNL);
       vty_out (vty, "    Neighbor Interface ID: %s%s",
                inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
-                          buf, sizeof (buf)), VTY_NEWLINE);
+                          buf, sizeof (buf)), VNL);
       vty_out (vty, "    Neighbor Router ID: %s%s",
                inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
-                          buf, sizeof (buf)), VTY_NEWLINE);
+                          buf, sizeof (buf)), VNL);
     }
   return 0;
 }
@@ -180,8 +180,8 @@ ospf6_router_lsa_originate_sub (struct ospf6_area *oa, int force)
           lsa_header->id = htonl (link_state_id);
           lsa_header->adv_router = oa->ospf6->router_id;
           lsa_header->seqnum =
-            ospf6_lsa_new_seqnum (lsa_header->type, lsa_header->id,
-                                  lsa_header->adv_router, oa);
+            ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
+                                 lsa_header->adv_router, oa->lsdb);
           lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
 
           /* LSA checksum */
@@ -268,8 +268,8 @@ ospf6_router_lsa_originate_sub (struct ospf6_area *oa, int force)
       lsa_header->id = htonl (link_state_id);
       lsa_header->adv_router = oa->ospf6->router_id;
       lsa_header->seqnum =
-        ospf6_lsa_new_seqnum (lsa_header->type, lsa_header->id,
-                              lsa_header->adv_router, oa);
+        ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
+                             lsa_header->adv_router, oa->lsdb);
       lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
 
       /* LSA checksum */
@@ -341,7 +341,7 @@ ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
     ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
 
   ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
-  vty_out (vty, "     Options: %s%s", options, VTY_NEWLINE);
+  vty_out (vty, "     Options: %s%s", options, VNL);
 
   start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
   end = (char *) lsa->header + ntohs (lsa->header->length);
@@ -350,7 +350,7 @@ ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
     {
       lsdesc = (struct ospf6_network_lsdesc *) current;
       inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
-      vty_out (vty, "     Attached Router: %s%s", buf, VTY_NEWLINE);
+      vty_out (vty, "     Attached Router: %s%s", buf, VNL);
     }
   return 0;
 }
@@ -457,8 +457,8 @@ ospf6_network_lsa_originate_sub (struct ospf6_interface *oi, int force)
   lsa_header->id = htonl (oi->interface->ifindex);
   lsa_header->adv_router = oi->area->ospf6->router_id;
   lsa_header->seqnum =
-    ospf6_lsa_new_seqnum (lsa_header->type, lsa_header->id,
-                          lsa_header->adv_router, oi->area);
+    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
+                         lsa_header->adv_router, oi->area->lsdb);
   lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
 
   /* LSA checksum */
@@ -523,9 +523,9 @@ ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
   prefixnum = ntohl (link_lsa->prefix_num);
 
   vty_out (vty, "     Priority: %d Options: %s%s",
-           link_lsa->priority, options, VTY_NEWLINE);
-  vty_out (vty, "     LinkLocal Address: %s%s", buf, VTY_NEWLINE);
-  vty_out (vty, "     Number of Prefix: %d%s", prefixnum, VTY_NEWLINE);
+           link_lsa->priority, options, VNL);
+  vty_out (vty, "     LinkLocal Address: %s%s", buf, VNL);
+  vty_out (vty, "     Number of Prefix: %d%s", prefixnum, VNL);
 
   start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
   end = (char *) lsa->header + ntohs (lsa->header->length); 
@@ -545,14 +545,14 @@ ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
       nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
            "NU" : "--");
       vty_out (vty, "     Prefix Options: %s|%s|%s|%s%s",
-               p, mc, la, nu, VTY_NEWLINE);
+               p, mc, la, nu, VNL);
 
       memset (&in6, 0, sizeof (in6));
       memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
               OSPF6_PREFIX_SPACE (prefix->prefix_length));
       inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
       vty_out (vty, "     Prefix: %s/%d%s",
-               buf, prefix->prefix_length, VTY_NEWLINE);
+               buf, prefix->prefix_length, VNL);
     }
 
   return 0;
@@ -632,8 +632,8 @@ ospf6_link_lsa_originate_sub (struct ospf6_interface *oi, int force)
   lsa_header->id = htonl (oi->interface->ifindex);
   lsa_header->adv_router = oi->area->ospf6->router_id;
   lsa_header->seqnum =
-    ospf6_lsa_new_seqnum (lsa_header->type, lsa_header->id,
-                          lsa_header->adv_router, oi);
+    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
+                         lsa_header->adv_router, oi->lsdb);
   lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
 
   /* LSA checksum */
@@ -696,14 +696,14 @@ ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
 
   prefixnum = ntohs (intra_prefix_lsa->prefix_num);
 
-  vty_out (vty, "     Number of Prefix: %d%s", prefixnum, VTY_NEWLINE);
+  vty_out (vty, "     Number of Prefix: %d%s", prefixnum, VNL);
 
   inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
   inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
              adv_router, sizeof (adv_router));
   vty_out (vty, "     Reference: %s Id: %s Adv: %s%s",
            OSPF6_LSTYPE_NAME (intra_prefix_lsa->ref_type), id, adv_router,
-           VTY_NEWLINE);
+           VNL);
 
   start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
   end = (char *) lsa->header + ntohs (lsa->header->length); 
@@ -723,14 +723,14 @@ ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
       nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
            "NU" : "--");
       vty_out (vty, "     Prefix Options: %s|%s|%s|%s%s",
-               p, mc, la, nu, VTY_NEWLINE);
+               p, mc, la, nu, VNL);
 
       memset (&in6, 0, sizeof (in6));
       memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
               OSPF6_PREFIX_SPACE (prefix->prefix_length));
       inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
       vty_out (vty, "     Prefix: %s/%d%s",
-               buf, prefix->prefix_length, VTY_NEWLINE);
+               buf, prefix->prefix_length, VNL);
     }
 
   return 0;
@@ -868,8 +868,8 @@ ospf6_intra_prefix_lsa_originate_stub_sub (struct ospf6_area *oa,
   lsa_header->id = htonl (0);
   lsa_header->adv_router = oa->ospf6->router_id;
   lsa_header->seqnum =
-    ospf6_lsa_new_seqnum (lsa_header->type, lsa_header->id,
-                          lsa_header->adv_router, oa);
+    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
+                         lsa_header->adv_router, oa->lsdb);
   lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
 
   /* LSA checksum */
@@ -1064,8 +1064,8 @@ ospf6_intra_prefix_lsa_originate_transit_sub (struct ospf6_interface *oi,
   lsa_header->id = htonl (oi->interface->ifindex);
   lsa_header->adv_router = oi->area->ospf6->router_id;
   lsa_header->seqnum =
-    ospf6_lsa_new_seqnum (lsa_header->type, lsa_header->id,
-                          lsa_header->adv_router, oi->area);
+    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
+                         lsa_header->adv_router, oi->area->lsdb);
   lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
 
   /* LSA checksum */

+ 33 - 62
ospf6d/ospf6_lsa.c

@@ -28,7 +28,6 @@
 #include "memory.h"
 #include "thread.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
@@ -40,6 +39,7 @@
 #include "ospf6_neighbor.h"
 
 #include "ospf6_flood.h"
+#include "ospf6d.h"
 
 unsigned char conf_debug_ospf6_lsa = 0;
 
@@ -283,24 +283,23 @@ ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
   inet_ntop (AF_INET, &lsa->header->adv_router,
              adv_router, sizeof (adv_router));
 
-  vty_out (vty, "%s", VTY_NEWLINE);
   vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
-           OSPF6_LSTYPE_NAME (lsa->header->type), VTY_NEWLINE);
-  vty_out (vty, "Link State ID: %s%s", id, VTY_NEWLINE);
-  vty_out (vty, "Advertising Router: %s%s", adv_router, VTY_NEWLINE);
+           OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
+  vty_out (vty, "Link State ID: %s%s", id, VNL);
+  vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
   vty_out (vty, "LS Sequence Number: %#010lx%s",
-           (u_long) ntohl (lsa->header->seqnum), VTY_NEWLINE);
+           (u_long) ntohl (lsa->header->seqnum), VNL);
   vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
            ntohs (lsa->header->checksum),
-           ntohs (lsa->header->length), VTY_NEWLINE);
+           ntohs (lsa->header->length), VNL);
 
   index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
   if (ospf6_lstype[index].show)
     (*ospf6_lstype[index].show) (vty, lsa);
   else
-    vty_out (vty, "%sUnknown LSA type ...%s", VTY_NEWLINE, VTY_NEWLINE);
+    vty_out (vty, "%sUnknown LSA type ...%s", VNL, VNL);
 
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, "%s", VNL);
 }
 
 void
@@ -308,7 +307,7 @@ ospf6_lsa_show_summary_header (struct vty *vty)
 {
   vty_out (vty, "%-12s %-15s %-15s %4s %8s %4s %4s %-8s%s",
            "Type", "LSId", "AdvRouter", "Age", "SeqNum",
-           "Cksm", "Len", "Duration", VTY_NEWLINE);
+           "Cksm", "Len", "Duration", VNL);
 }
 
 void
@@ -334,7 +333,7 @@ ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa)
            id, adv_router, ospf6_lsa_age_current (lsa),
            (u_long) ntohl (lsa->header->seqnum),
            ntohs (lsa->header->checksum), ntohs (lsa->header->length),
-           duration, VTY_NEWLINE);
+           duration, VNL);
 }
 
 void
@@ -346,13 +345,13 @@ ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
   start = (char *) lsa->header;
   end = (char *) lsa->header + ntohs (lsa->header->length);
 
-  vty_out (vty, "%s", VTY_NEWLINE);
-  vty_out (vty, "%s:%s", lsa->name, VTY_NEWLINE);
+  vty_out (vty, "%s", VNL);
+  vty_out (vty, "%s:%s", lsa->name, VNL);
 
   for (current = start; current < end; current ++)
     {
       if ((current - start) % 16 == 0)
-        vty_out (vty, "%s        ", VTY_NEWLINE);
+        vty_out (vty, "%s        ", VNL);
       else if ((current - start) % 4 == 0)
         vty_out (vty, " ");
 
@@ -360,7 +359,7 @@ ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
       vty_out (vty, "%s", byte);
     }
 
-  vty_out (vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE);
+  vty_out (vty, "%s%s", VNL, VNL);
 }
 
 void
@@ -374,51 +373,23 @@ ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa)
   inet_ntop (AF_INET, &lsa->header->adv_router,
              adv_router, sizeof (adv_router));
 
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, "%s", VNL);
   vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
-           OSPF6_LSTYPE_NAME (lsa->header->type), VTY_NEWLINE);
-  vty_out (vty, "Link State ID: %s%s", id, VTY_NEWLINE);
-  vty_out (vty, "Advertising Router: %s%s", adv_router, VTY_NEWLINE);
+           OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
+  vty_out (vty, "Link State ID: %s%s", id, VNL);
+  vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
   vty_out (vty, "LS Sequence Number: %#010lx%s",
-           (u_long) ntohl (lsa->header->seqnum), VTY_NEWLINE);
+           (u_long) ntohl (lsa->header->seqnum), VNL);
   vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
            ntohs (lsa->header->checksum),
-           ntohs (lsa->header->length), VTY_NEWLINE);
+           ntohs (lsa->header->length), VNL);
   vty_out (vty, "    Prev: %p This: %p Next: %p%s",
-           lsa->prev, lsa, lsa->next, VTY_NEWLINE);
-  vty_out (vty, "%s", VTY_NEWLINE);
+           lsa->prev, lsa, lsa->next, VNL);
+  vty_out (vty, "%s", VNL);
 }
 
 /* OSPFv3 LSA creation/deletion function */
 
-/* calculate LS sequence number for my new LSA.
-   return value is network byte order */
-u_int32_t
-ospf6_lsa_new_seqnum (u_int16_t type, u_int32_t id, u_int32_t adv_router,
-                      void *scope)
-{
-  struct ospf6_lsdb *lsdb = NULL;
-  struct ospf6_lsa *lsa;
-  signed long seqnum = 0;
-
-  /* get current database copy */
-  lsdb = ospf6_get_scoped_lsdb (type, scope);
-  if (lsdb == NULL)
-    {
-      zlog_warn ("Can't decide scoped LSDB");
-      return ((u_int32_t) htonl (INITIAL_SEQUENCE_NUMBER));
-    }
-
-  /* if current database copy not found, return InitialSequenceNumber */
-  lsa = ospf6_lsdb_lookup (type, id, adv_router, lsdb);
-  if (lsa == NULL)
-    seqnum = INITIAL_SEQUENCE_NUMBER;
-  else
-    seqnum = (signed long) ntohl (lsa->header->seqnum) + 1;
-
-  return ((u_int32_t) htonl (seqnum));
-}
-
 struct ospf6_lsa *
 ospf6_lsa_create (struct ospf6_lsa_header *header)
 {
@@ -752,11 +723,11 @@ ospf6_unknown_show (struct vty *vty, struct ospf6_lsa *lsa)
   start = (char *) lsa->header + sizeof (struct ospf6_lsa_header);
   end = (char *) lsa->header + ntohs (lsa->header->length);
 
-  vty_out (vty, "        Unknown contents:%s", VTY_NEWLINE);
+  vty_out (vty, "        Unknown contents:%s", VNL);
   for (current = start; current < end; current ++)
     {
       if ((current - start) % 16 == 0)
-        vty_out (vty, "%s        ", VTY_NEWLINE);
+        vty_out (vty, "%s        ", VNL);
       else if ((current - start) % 4 == 0)
         vty_out (vty, " ");
 
@@ -764,7 +735,7 @@ ospf6_unknown_show (struct vty *vty, struct ospf6_lsa *lsa)
       vty_out (vty, "%s", byte);
     }
 
-  vty_out (vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE);
+  vty_out (vty, "%s%s", VNL, VNL);
   return 0;
 }
 
@@ -899,27 +870,27 @@ int
 config_write_ospf6_debug_lsa (struct vty *vty)
 {
   if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_ALL)
-    vty_out (vty, "debug ospf6 lsa all%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 lsa all%s", VNL);
   else
     {
       if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_DEFAULT)
-        vty_out (vty, "debug ospf6 lsa%s", VTY_NEWLINE);
+        vty_out (vty, "debug ospf6 lsa%s", VNL);
       else
         {
           if (IS_OSPF6_DEBUG_LSA (SEND))
-            vty_out (vty, "debug ospf6 lsa send%s", VTY_NEWLINE);
+            vty_out (vty, "debug ospf6 lsa send%s", VNL);
           if (IS_OSPF6_DEBUG_LSA (RECV))
-            vty_out (vty, "debug ospf6 lsa recv%s", VTY_NEWLINE);
+            vty_out (vty, "debug ospf6 lsa recv%s", VNL);
           if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
-            vty_out (vty, "debug ospf6 lsa originate%s", VTY_NEWLINE);
+            vty_out (vty, "debug ospf6 lsa originate%s", VNL);
           if (IS_OSPF6_DEBUG_LSA (TIMER))
-            vty_out (vty, "debug ospf6 lsa timer%s", VTY_NEWLINE);
+            vty_out (vty, "debug ospf6 lsa timer%s", VNL);
         }
 
       if (IS_OSPF6_DEBUG_LSA (DATABASE))
-        vty_out (vty, "debug ospf6 lsa database%s", VTY_NEWLINE);
+        vty_out (vty, "debug ospf6 lsa database%s", VNL);
       if (IS_OSPF6_DEBUG_LSA (MEMORY))
-        vty_out (vty, "debug ospf6 lsa memory%s", VTY_NEWLINE);
+        vty_out (vty, "debug ospf6 lsa memory%s", VNL);
     }
 
   return 0;

+ 0 - 3
ospf6d/ospf6_lsa.h

@@ -225,9 +225,6 @@ void ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa);
 void ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa);
 void ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa);
 
-u_int32_t ospf6_lsa_new_seqnum (u_int16_t type, u_int32_t id,
-                                u_int32_t adv_router, void *scope);
-
 struct ospf6_lsa *ospf6_lsa_create (struct ospf6_lsa_header *header);
 struct ospf6_lsa *ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header);
 void ospf6_lsa_delete (struct ospf6_lsa *lsa);

+ 97 - 1
ospf6d/ospf6_lsdb.c

@@ -26,11 +26,12 @@
 #include "command.h"
 #include "prefix.h"
 #include "table.h"
+#include "vty.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
+#include "ospf6d.h"
 
 struct ospf6_lsdb *
 ospf6_lsdb_create ()
@@ -405,4 +406,99 @@ ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb)
     ospf6_lsdb_remove (lsa, lsdb);
 }
 
+void
+ospf6_lsdb_show (struct vty *vty, int level,
+                 u_int16_t *type, u_int32_t *id, u_int32_t *adv_router,
+                 struct ospf6_lsdb *lsdb)
+{
+  struct ospf6_lsa *lsa;
+  void (*showfunc) (struct vty *, struct ospf6_lsa *) = NULL;
+
+  if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
+    showfunc = ospf6_lsa_show_summary;
+  else if (level == OSPF6_LSDB_SHOW_LEVEL_DETAIL)
+    showfunc = ospf6_lsa_show;
+  else if (level == OSPF6_LSDB_SHOW_LEVEL_INTERNAL)
+    showfunc = ospf6_lsa_show_internal;
+  else if (level == OSPF6_LSDB_SHOW_LEVEL_DUMP)
+    showfunc = ospf6_lsa_show_dump;
+
+  if (type && id && adv_router)
+    {
+      lsa = ospf6_lsdb_lookup (*type, *id, *adv_router, lsdb);
+      if (lsa)
+        {
+          if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
+            ospf6_lsa_show (vty, lsa);
+          else
+            (*showfunc) (vty, lsa);
+        }
+      return;
+    }
+
+  if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
+    ospf6_lsa_show_summary_header (vty);
+
+  if (type && adv_router)
+    lsa = ospf6_lsdb_type_router_head (*type, *adv_router, lsdb);
+  else if (type)
+    lsa = ospf6_lsdb_type_head (*type, lsdb);
+  else
+    lsa = ospf6_lsdb_head (lsdb);
+  while (lsa)
+    {
+      if ((! adv_router || lsa->header->adv_router == *adv_router) &&
+          (! id || lsa->header->id == *id))
+        (*showfunc) (vty, lsa);
+
+      if (type && adv_router)
+        lsa = ospf6_lsdb_type_router_next (*type, *adv_router, lsa);
+      else if (type)
+        lsa = ospf6_lsdb_type_next (*type, lsa);
+      else
+        lsa = ospf6_lsdb_next (lsa);
+    }
+}
+
+/* Decide new Link State ID to originate.
+   note return value is network byte order */
+u_int32_t
+ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router,
+                 struct ospf6_lsdb *lsdb)
+{
+  struct ospf6_lsa *lsa;
+  u_int32_t id = 1;
+
+  for (lsa = ospf6_lsdb_type_router_head (type, adv_router, lsdb); lsa;
+       lsa = ospf6_lsdb_type_router_next (type, adv_router, lsa))
+    {
+      if (ntohl (lsa->header->id) < id)
+        continue;
+      if (ntohl (lsa->header->id) > id)
+        return ((u_int32_t) htonl (id));
+      id++;
+    }
+
+  return ((u_int32_t) htonl (id));
+}
+
+/* Decide new LS sequence number to originate.
+   note return value is network byte order */
+u_int32_t
+ospf6_new_ls_seqnum (u_int16_t type, u_int32_t id, u_int32_t adv_router,
+                     struct ospf6_lsdb *lsdb)
+{
+  struct ospf6_lsa *lsa;
+  signed long seqnum = 0;
+
+  /* if current database copy not found, return InitialSequenceNumber */
+  lsa = ospf6_lsdb_lookup (type, id, adv_router, lsdb);
+  if (lsa == NULL)
+    seqnum = INITIAL_SEQUENCE_NUMBER;
+  else
+    seqnum = (signed long) ntohl (lsa->header->seqnum) + 1;
+
+  return ((u_int32_t) htonl (seqnum));
+}
+
 

+ 13 - 87
ospf6d/ospf6_lsdb.h

@@ -33,87 +33,6 @@ struct ospf6_lsdb
   void (*hook_remove) (struct ospf6_lsa *);
 };
 
-#define LSDB_FOREACH_LSA(vty, func, lsdb)                             \
-  do {                                                                \
-    struct ospf6_lsa *lsa;                                            \
-    for (lsa = ospf6_lsdb_head (lsdb); lsa;                           \
-         lsa = ospf6_lsdb_next (lsa))                                 \
-      {                                                               \
-        (*(func)) (vty, lsa);                                         \
-      }                                                               \
-  } while (0)
-#define LSDB_FOREACH_LSA_T(vty, func, lsdb, type)                     \
-  do {                                                                \
-    struct ospf6_lsa *lsa;                                            \
-    for (lsa = ospf6_lsdb_type_head (type, lsdb); lsa;                \
-         lsa = ospf6_lsdb_type_next (type, lsa))                      \
-      {                                                               \
-        (*(func)) (vty, lsa);                                         \
-      }                                                               \
-  } while (0)
-#define LSDB_FOREACH_LSA_I(vty, func, lsdb, id)                       \
-  do {                                                                \
-    struct ospf6_lsa *lsa;                                            \
-    for (lsa = ospf6_lsdb_head (lsdb); lsa;                           \
-         lsa = ospf6_lsdb_next (lsa))                                 \
-      {                                                               \
-        if (lsa->header->id != id)                                    \
-          continue;                                                   \
-        (*(func)) (vty, lsa);                                         \
-      }                                                               \
-  } while (0)
-#define LSDB_FOREACH_LSA_R(vty, func, lsdb, router)                   \
-  do {                                                                \
-    struct ospf6_lsa *lsa;                                            \
-    for (lsa = ospf6_lsdb_head (lsdb); lsa;                           \
-         lsa = ospf6_lsdb_next (lsa))                                 \
-      {                                                               \
-        if (lsa->header->adv_router != router)                        \
-          continue;                                                   \
-        (*(func)) (vty, lsa);                                         \
-      }                                                               \
-  } while (0)
-#define LSDB_FOREACH_LSA_TI(vty, func, lsdb, type, id)                \
-  do {                                                                \
-    struct ospf6_lsa *lsa;                                            \
-    for (lsa = ospf6_lsdb_type_head (type, lsdb); lsa;                \
-         lsa = ospf6_lsdb_type_next (type, lsa))                      \
-      {                                                               \
-        if (lsa->header->id != id)                                    \
-          continue;                                                   \
-        (*(func)) (vty, lsa);                                         \
-      }                                                               \
-  } while (0)
-#define LSDB_FOREACH_LSA_TR(vty, func, lsdb, type, router)            \
-  do {                                                                \
-    struct ospf6_lsa *lsa;                                            \
-    for (lsa = ospf6_lsdb_type_router_head (type, router, lsdb); lsa; \
-         lsa = ospf6_lsdb_type_router_next (type, router, lsa))       \
-      {                                                               \
-        (*(func)) (vty, lsa);                                         \
-      }                                                               \
-  } while (0)
-#define LSDB_FOREACH_LSA_IR(vty, func, lsdb, id, router)              \
-  do {                                                                \
-    struct ospf6_lsa *lsa;                                            \
-    for (lsa = ospf6_lsdb_head (lsdb); lsa;                           \
-         lsa = ospf6_lsdb_next (lsa))                                 \
-      {                                                               \
-        if (lsa->header->adv_router != router)                        \
-          continue;                                                   \
-        if (lsa->header->id != id)                                    \
-          continue;                                                   \
-        (*(func)) (vty, lsa);                                         \
-      }                                                               \
-  } while (0)
-#define LSDB_FOREACH_LSA_TIR(vty, func, lsdb, type, id, router)       \
-  do {                                                                \
-    struct ospf6_lsa *lsa;                                            \
-    lsa = ospf6_lsdb_lookup (type, id, router, lsdb);                 \
-    if (lsa)                                                          \
-      (*(func)) (vty, lsa);                                           \
-  } while (0)
-
 #define OSPF6_LSDB_MAXAGE_REMOVER(lsdb)                                  \
   do {                                                                   \
     struct ospf6_lsa *lsa;                                               \
@@ -157,13 +76,20 @@ struct ospf6_lsa *ospf6_lsdb_type_next (u_int16_t type,
 
 void ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb);
 
-int ospf6_lsdb_show (struct vty *vty, int argc, char **argv,
-                     struct ospf6_lsdb *lsdb);
+#define OSPF6_LSDB_SHOW_LEVEL_NORMAL   0
+#define OSPF6_LSDB_SHOW_LEVEL_DETAIL   1
+#define OSPF6_LSDB_SHOW_LEVEL_INTERNAL 2
+#define OSPF6_LSDB_SHOW_LEVEL_DUMP     3
+
+void ospf6_lsdb_show
+  (struct vty *vty, int level,
+   u_int16_t *type, u_int32_t *id, u_int32_t *adv_router,
+   struct ospf6_lsdb *lsdb);
 
-#if 0
-void ospf6_lsdb_init ();
-void ospf6_lsdb_remove_maxage (struct ospf6_lsdb *lsdb);
-#endif
+u_int32_t ospf6_new_ls_id
+  (u_int16_t type, u_int32_t adv_router, struct ospf6_lsdb *lsdb);
+u_int32_t ospf6_new_ls_seqnum
+  (u_int16_t type, u_int32_t id, u_int32_t adv_router, struct ospf6_lsdb *lsdb);
 
 #endif /* OSPF6_LSDB_H */
 

+ 12 - 11
ospf6d/ospf6_message.c

@@ -28,7 +28,6 @@
 #include "thread.h"
 #include "linklist.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
@@ -41,6 +40,7 @@
 #include "ospf6_interface.h"
 
 #include "ospf6_flood.h"
+#include "ospf6d.h"
 
 unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
 char *ospf6_message_type_str[] =
@@ -2018,7 +2018,8 @@ DEFUN (no_debug_ospf6_message,
 
 ALIAS (no_debug_ospf6_message,
        no_debug_ospf6_message_sendrecv_cmd,
-       "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
+       "no debug ospf6 message "
+       "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
        NO_STR
        DEBUG_STR
        OSPF6_STR
@@ -2052,41 +2053,41 @@ config_write_ospf6_debug_message (struct vty *vty)
 
   if (s == 0x3f && r == 0x3f)
     {
-      vty_out (vty, "debug ospf6 message all%s", VTY_NEWLINE);
+      vty_out (vty, "debug ospf6 message all%s", VNL);
       return 0;
     }
 
   if (s == 0x3f && r == 0)
     {
-      vty_out (vty, "debug ospf6 message all send%s", VTY_NEWLINE);
+      vty_out (vty, "debug ospf6 message all send%s", VNL);
       return 0;
     }
   else if (s == 0 && r == 0x3f)
     {
-      vty_out (vty, "debug ospf6 message all recv%s", VTY_NEWLINE);
+      vty_out (vty, "debug ospf6 message all recv%s", VNL);
       return 0;
     }
 
   /* Unknown message is logged by default */
   if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) &&
       ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
-    vty_out (vty, "no debug ospf6 message unknown%s", VTY_NEWLINE);
+    vty_out (vty, "no debug ospf6 message unknown%s", VNL);
   else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
-    vty_out (vty, "no debug ospf6 message unknown send%s", VTY_NEWLINE);
+    vty_out (vty, "no debug ospf6 message unknown send%s", VNL);
   else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
-    vty_out (vty, "no debug ospf6 message unknown recv%s", VTY_NEWLINE);
+    vty_out (vty, "no debug ospf6 message unknown recv%s", VNL);
 
   for (i = 1; i < 6; i++)
     {
       if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) &&
           IS_OSPF6_DEBUG_MESSAGE (i, RECV))
-        vty_out (vty, "debug ospf6 message %s%s", type_str[i], VTY_NEWLINE);
+        vty_out (vty, "debug ospf6 message %s%s", type_str[i], VNL);
       else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
         vty_out (vty, "debug ospf6 message %s send%s", type_str[i],
-                 VTY_NEWLINE);
+                 VNL);
       else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
         vty_out (vty, "debug ospf6 message %s recv%s", type_str[i],
-                 VTY_NEWLINE);
+                 VNL);
     }
 
   return 0;

+ 31 - 31
ospf6d/ospf6_neighbor.c

@@ -28,7 +28,6 @@
 #include "vty.h"
 #include "command.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
@@ -39,6 +38,7 @@
 #include "ospf6_neighbor.h"
 #include "ospf6_intra.h"
 #include "ospf6_flood.h"
+#include "ospf6d.h"
 
 unsigned char conf_debug_ospf6_neighbor = 0;
 
@@ -625,14 +625,14 @@ ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
   /*
   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
            "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
-           "I/F", "State", VTY_NEWLINE);
+           "I/F", "State", VNL);
   */
 
   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
            router_id, on->priority, deadtime,
            ospf6_neighbor_state_str[on->state], nstate, duration,
            on->ospf6_if->interface->name,
-           ospf6_interface_state_str[on->ospf6_if->state], VTY_NEWLINE);
+           ospf6_interface_state_str[on->ospf6_if->state], VNL);
 }
 
 void
@@ -646,7 +646,7 @@ ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
 /*
     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
-             "State", VTY_NEWLINE);
+             "State", VNL);
 */
 
   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
@@ -661,7 +661,7 @@ ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
            router_id, ospf6_neighbor_state_str[on->state],
            duration, drouter, bdrouter, on->ospf6_if->interface->name,
            ospf6_interface_state_str[on->ospf6_if->state],
-           VTY_NEWLINE);
+           VNL);
 }
 
 void
@@ -682,45 +682,45 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
   timerstring (&res, duration, sizeof (duration));
 
   vty_out (vty, " Neighbor %s%s", on->name,
-           VTY_NEWLINE);
+           VNL);
   vty_out (vty, "    Area %s via interface %s (ifindex %d)%s",
            on->ospf6_if->area->name,
            on->ospf6_if->interface->name,
            on->ospf6_if->interface->ifindex,
-           VTY_NEWLINE);
+           VNL);
   vty_out (vty, "    His IfIndex: %d Link-local address: %s%s",
            on->ifindex, linklocal_addr,
-           VTY_NEWLINE);
+           VNL);
   vty_out (vty, "    State %s for a duration of %s%s",
            ospf6_neighbor_state_str[on->state], duration,
-           VTY_NEWLINE);
+           VNL);
   vty_out (vty, "    His choice of DR/BDR %s/%s, Priority %d%s",
            drouter, bdrouter, on->priority,
-           VTY_NEWLINE);
+           VNL);
   vty_out (vty, "    DbDesc status: %s%s%s SeqNum: %#lx%s",
            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " : ""),
            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""),
            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ?
             "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum),
-           VTY_NEWLINE);
+           VNL);
 
   vty_out (vty, "    Summary-List: %d LSAs%s", on->summary_list->count,
-           VTY_NEWLINE);
+           VNL);
   for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
-    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);
+    vty_out (vty, "      %s%s", lsa->name, VNL);
 
   vty_out (vty, "    Request-List: %d LSAs%s", on->request_list->count,
-           VTY_NEWLINE);
+           VNL);
   for (lsa = ospf6_lsdb_head (on->request_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
-    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);
+    vty_out (vty, "      %s%s", lsa->name, VNL);
 
   vty_out (vty, "    Retrans-List: %d LSAs%s", on->retrans_list->count,
-           VTY_NEWLINE);
+           VNL);
   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
-    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);
+    vty_out (vty, "      %s%s", lsa->name, VNL);
 
   timerclear (&res);
   if (on->thread_send_dbdesc)
@@ -729,10 +729,10 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
   vty_out (vty, "    %d Pending LSAs for DbDesc in Time %s [thread %s]%s",
            on->dbdesc_list->count, duration,
            (on->thread_send_dbdesc ? "on" : "off"),
-           VTY_NEWLINE);
+           VNL);
   for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
-    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);
+    vty_out (vty, "      %s%s", lsa->name, VNL);
 
   timerclear (&res);
   if (on->thread_send_lsreq)
@@ -741,10 +741,10 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
   vty_out (vty, "    %d Pending LSAs for LSReq in Time %s [thread %s]%s",
            on->lsreq_list->count, duration,
            (on->thread_send_lsreq ? "on" : "off"),
-           VTY_NEWLINE);
+           VNL);
   for (lsa = ospf6_lsdb_head (on->lsreq_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
-    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);
+    vty_out (vty, "      %s%s", lsa->name, VNL);
 
   timerclear (&res);
   if (on->thread_send_lsupdate)
@@ -753,10 +753,10 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
   vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
            on->lsupdate_list->count, duration,
            (on->thread_send_lsupdate ? "on" : "off"),
-           VTY_NEWLINE);
+           VNL);
   for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
-    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);
+    vty_out (vty, "      %s%s", lsa->name, VNL);
 
   timerclear (&res);
   if (on->thread_send_lsack)
@@ -765,10 +765,10 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
   vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
            on->lsack_list->count, duration,
            (on->thread_send_lsack ? "on" : "off"),
-           VTY_NEWLINE);
+           VNL);
   for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
-    vty_out (vty, "      %s%s", lsa->name, VTY_NEWLINE);
+    vty_out (vty, "      %s%s", lsa->name, VNL);
 
 }
 
@@ -801,11 +801,11 @@ DEFUN (show_ipv6_ospf6_neighbor,
   if (showfunc == ospf6_neighbor_show)
     vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
              "Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
-             "I/F", "State", VTY_NEWLINE);
+             "I/F", "State", VNL);
   else if (showfunc == ospf6_neighbor_show_drchoice)
     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
-             "State", VTY_NEWLINE);
+             "State", VNL);
 
   for (i = listhead (ospf6->area_list); i; nextnode (i))
     {
@@ -857,7 +857,7 @@ DEFUN (show_ipv6_ospf6_neighbor_one,
   if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
     {
       vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
-               VTY_NEWLINE);
+               VNL);
       return CMD_SUCCESS;
     }
 
@@ -960,11 +960,11 @@ config_write_ospf6_debug_neighbor (struct vty *vty)
 {
   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) &&
       IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
-    vty_out (vty, "debug ospf6 neighbor%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 neighbor%s", VNL);
   else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
-    vty_out (vty, "debug ospf6 neighbor state%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 neighbor state%s", VNL);
   else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
-    vty_out (vty, "debug ospf6 neighbor event%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 neighbor event%s", VNL);
   return 0;
 }
 

+ 1 - 0
ospf6d/ospf6_proto.h

@@ -1,4 +1,5 @@
 /*
+ * Common protocol data and data structures.
  * Copyright (C) 2003 Yasuhiro Ohara
  *
  * This file is part of GNU Zebra.

+ 37 - 36
ospf6d/ospf6_route.c

@@ -28,10 +28,11 @@
 #include "vty.h"
 #include "command.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_lsa.h"
+#include "ospf6_lsdb.h"
 #include "ospf6_route.h"
+#include "ospf6d.h"
 
 unsigned char conf_debug_ospf6_route = 0;
 
@@ -627,7 +628,7 @@ ospf6_route_show (struct vty *vty, struct ospf6_route *route)
            (ospf6_route_is_best (route) ? '*' : ' '),
            OSPF6_DEST_TYPE_SUBSTR (route->type),
            OSPF6_PATH_TYPE_SUBSTR (route->path.type),
-           destination, nexthop, ifname, duration, VTY_NEWLINE);
+           destination, nexthop, ifname, duration, VNL);
 
   for (i = 1; ospf6_nexthop_is_set (&route->nexthop[i]) &&
        i < OSPF6_MULTI_PATH_LIMIT; i++)
@@ -639,7 +640,7 @@ ospf6_route_show (struct vty *vty, struct ospf6_route *route)
         snprintf (ifname, sizeof (ifname), "%d", route->nexthop[i].ifindex);
 
       vty_out (vty, "%c%1s %2s %-30s %-25s %6s %s%s",
-               ' ', "", "", "", nexthop, ifname, "", VTY_NEWLINE);
+               ' ', "", "", "", nexthop, ifname, "", VNL);
     }
 }
 
@@ -663,21 +664,21 @@ ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route)
                destination, sizeof (destination));
   else
     prefix2str (&route->prefix, destination, sizeof (destination));
-  vty_out (vty, "Destination: %s%s", destination, VTY_NEWLINE);
+  vty_out (vty, "Destination: %s%s", destination, VNL);
 
   /* destination type */
   vty_out (vty, "Destination type: %s%s",
            OSPF6_DEST_TYPE_NAME (route->type),
-           VTY_NEWLINE);
+           VNL);
 
   /* Time */
   timersub (&now, &route->installed, &res);
   timerstring (&res, duration, sizeof (duration));
-  vty_out (vty, "Installed Time: %s ago%s", duration, VTY_NEWLINE);
+  vty_out (vty, "Installed Time: %s ago%s", duration, VNL);
 
   timersub (&now, &route->changed, &res);
   timerstring (&res, duration, sizeof (duration));
-  vty_out (vty, "  Changed Time: %s ago%s", duration, VTY_NEWLINE);
+  vty_out (vty, "  Changed Time: %s ago%s", duration, VNL);
 
   /* Debugging info */
   vty_out (vty, "Lock: %d Flags: %s%s%s%s%s", route->lock,
@@ -685,19 +686,19 @@ ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route)
            (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD)    ? "A" : "-"),
            (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
            (CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"),
-           VTY_NEWLINE);
+           VNL);
   vty_out (vty, "Memory: prev: %p this: %p next: %p%s",
-           route->prev, route, route->next, VTY_NEWLINE);
+           route->prev, route, route->next, VNL);
 
   /* Path section */
 
   /* Area-ID */
   inet_ntop (AF_INET, &route->path.area_id, area_id, sizeof (area_id));
-  vty_out (vty, "Associated Area: %s%s", area_id, VTY_NEWLINE);
+  vty_out (vty, "Associated Area: %s%s", area_id, VNL);
 
   /* Path type */
   vty_out (vty, "Path Type: %s%s",
-           OSPF6_PATH_TYPE_NAME (route->path.type), VTY_NEWLINE);
+           OSPF6_PATH_TYPE_NAME (route->path.type), VNL);
 
   /* LS Origin */
   inet_ntop (AF_INET, &route->path.origin.id, id, sizeof (id));
@@ -705,27 +706,27 @@ ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route)
              sizeof (adv_router));
   vty_out (vty, "LS Origin: %s Id: %s Adv: %s%s",
            OSPF6_LSTYPE_NAME (route->path.origin.type),
-           id, adv_router, VTY_NEWLINE);
+           id, adv_router, VNL);
 
   /* Options */
   ospf6_options_printbuf (route->path.options, options, sizeof (options));
-  vty_out (vty, "Options: %s%s", options, VTY_NEWLINE);
+  vty_out (vty, "Options: %s%s", options, VNL);
 
   /* Router Bits */
   ospf6_capability_printbuf (route->path.router_bits, capa, sizeof (capa));
-  vty_out (vty, "Router Bits: %s%s", capa, VTY_NEWLINE);
+  vty_out (vty, "Router Bits: %s%s", capa, VNL);
 
   /* Prefix Options */
-  vty_out (vty, "Prefix Options: xxx%s", VTY_NEWLINE);
+  vty_out (vty, "Prefix Options: xxx%s", VNL);
 
   /* Metrics */
   vty_out (vty, "Metric Type: %d%s", route->path.metric_type,
-           VTY_NEWLINE);
+           VNL);
   vty_out (vty, "Metric: %d (%d)%s",
-           route->path.cost, route->path.cost_e2, VTY_NEWLINE);
+           route->path.cost, route->path.cost_e2, VNL);
 
   /* Nexthops */
-  vty_out (vty, "Nexthop:%s", VTY_NEWLINE);
+  vty_out (vty, "Nexthop:%s", VNL);
   for (i = 0; ospf6_nexthop_is_set (&route->nexthop[i]) &&
        i < OSPF6_MULTI_PATH_LIMIT; i++)
     {
@@ -734,9 +735,9 @@ ospf6_route_show_detail (struct vty *vty, struct ospf6_route *route)
                  sizeof (nexthop));
       if (! if_indextoname (route->nexthop[i].ifindex, ifname))
         snprintf (ifname, sizeof (ifname), "%d", route->nexthop[i].ifindex);
-      vty_out (vty, "  %s %s%s", nexthop, ifname, VTY_NEWLINE);
+      vty_out (vty, "  %s %s%s", nexthop, ifname, VNL);
     }
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, "%s", VNL);
 }
 
 void
@@ -780,24 +781,24 @@ ospf6_route_show_table_summary (struct vty *vty,
 
   assert (number == table->count);
   vty_out (vty, "Number of Destination: %d (%d routes)%s",
-           destination, number, VTY_NEWLINE);
+           destination, number, VNL);
   if (multipath)
-    vty_out (vty, "  Number of Multi-path: %d%s", multipath, VTY_NEWLINE);
+    vty_out (vty, "  Number of Multi-path: %d%s", multipath, VNL);
   if (desttype_mismatch)
     vty_out (vty, "  Number of Different Dest-type: %d%s",
-             desttype_mismatch, VTY_NEWLINE);
+             desttype_mismatch, VNL);
   if (ecmp)
     vty_out (vty, "  Number of Equal Cost Multi Path: %d%s",
-             ecmp, VTY_NEWLINE);
+             ecmp, VNL);
   if (ecmp)
     vty_out (vty, "  Number of Invalid Nexthop: %d%s",
-             nhinval, VTY_NEWLINE);
+             nhinval, VNL);
 
   for (i = 0; i < OSPF6_PATH_TYPE_MAX; i++)
     {
       if (pathtype[i])
         vty_out (vty, "  Number of %s routes: %d%s",
-                 OSPF6_PATH_TYPE_NAME (i), pathtype[i], VTY_NEWLINE);
+                 OSPF6_PATH_TYPE_NAME (i), pathtype[i], VNL);
     }
 }
 
@@ -841,14 +842,14 @@ ospf6_route_table_show (struct vty *vty, int argc, char **argv,
 
       if (prefix.family)
         {
-          vty_out (vty, "Invalid argument: %s%s", argv[i], VTY_NEWLINE);
+          vty_out (vty, "Invalid argument: %s%s", argv[i], VNL);
           return CMD_SUCCESS;
         }
 
       ret = str2prefix (argv[i], &prefix);
       if (ret != 1 || prefix.family != AF_INET6)
         {
-          vty_out (vty, "Malformed argument: %s%s", argv[i], VTY_NEWLINE);
+          vty_out (vty, "Malformed argument: %s%s", argv[i], VNL);
           return CMD_SUCCESS;
         }
 
@@ -944,7 +945,7 @@ ospf6_lsentry_table_show (struct vty *vty, int argc, char **argv,
 
       if (adv_router.family && id.family)
         {
-          vty_out (vty, "Invalid argument: %s%s", argv[i], VTY_NEWLINE);
+          vty_out (vty, "Invalid argument: %s%s", argv[i], VNL);
           return CMD_SUCCESS;
         }
 
@@ -962,7 +963,7 @@ ospf6_lsentry_table_show (struct vty *vty, int argc, char **argv,
             }
           if (ret != 1)
             {
-              vty_out (vty, "Invalid Router-ID: %s%s", argv[i], VTY_NEWLINE);
+              vty_out (vty, "Invalid Router-ID: %s%s", argv[i], VNL);
               return CMD_SUCCESS;
             }
         }
@@ -985,7 +986,7 @@ ospf6_lsentry_table_show (struct vty *vty, int argc, char **argv,
           if (ret != 1)
             {
               vty_out (vty, "Invalid Link state ID: %s%s", argv[i],
-                       VTY_NEWLINE);
+                       VNL);
               return CMD_WARNING;
             }
         }
@@ -999,7 +1000,7 @@ ospf6_lsentry_table_show (struct vty *vty, int argc, char **argv,
         {
           vty_out (vty, "Specifying Link State ID by prefix is not allowed%s"
                    "when specifying Router-ID as wildcard%s",
-                   VTY_NEWLINE, VTY_NEWLINE);
+                   VNL, VNL);
           return CMD_SUCCESS;
         }
       else if (adv_router.prefixlen != 0 &&
@@ -1007,7 +1008,7 @@ ospf6_lsentry_table_show (struct vty *vty, int argc, char **argv,
         {
           vty_out (vty, "Specifying Link State ID is not allowed%s"
                    "when specifying Router-ID by prefix%s",
-                   VTY_NEWLINE, VTY_NEWLINE);
+                   VNL, VNL);
           return CMD_SUCCESS;
         }
 
@@ -1116,11 +1117,11 @@ int
 config_write_ospf6_debug_route (struct vty *vty)
 {
   if (IS_OSPF6_DEBUG_ROUTE (TABLE))
-    vty_out (vty, "debug ospf6 route table%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 route table%s", VNL);
   if (IS_OSPF6_DEBUG_ROUTE (INTRA))
-    vty_out (vty, "debug ospf6 route intra-area%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 route intra-area%s", VNL);
   if (IS_OSPF6_DEBUG_ROUTE (INTER))
-    vty_out (vty, "debug ospf6 route inter-area%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 route inter-area%s", VNL);
   return 0;
 }
 

+ 4 - 0
ospf6d/ospf6_route.h

@@ -137,6 +137,9 @@ struct ospf6_route
 
   /* route option */
   void *route_option;
+
+  /* link state id for advertising */
+  u_int32_t linkstate_id;
 };
 
 #define OSPF6_DEST_TYPE_NONE       0
@@ -150,6 +153,7 @@ struct ospf6_route
 #define OSPF6_ROUTE_ADD         0x02
 #define OSPF6_ROUTE_REMOVE      0x04
 #define OSPF6_ROUTE_BEST        0x08
+#define OSPF6_ROUTE_HAVE_LONGER 0x10
 
 struct ospf6_route_table
 {

+ 5 - 5
ospf6d/ospf6_spf.c

@@ -32,7 +32,6 @@
 #include "linklist.h"
 #include "thread.h"
 
-#include "ospf6d.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
 #include "ospf6_route.h"
@@ -40,6 +39,7 @@
 #include "ospf6_spf.h"
 #include "ospf6_intra.h"
 #include "ospf6_interface.h"
+#include "ospf6d.h"
 
 unsigned char conf_debug_ospf6_spf = 0;
 
@@ -532,13 +532,13 @@ ospf6_spf_display_subtree (struct vty *vty, char *prefix, int rest,
   int restnum;
 
   /* "prefix" is the space prefix of the display line */
-  vty_out (vty, "%s+-%s [%d]%s", prefix, v->name, v->cost, VTY_NEWLINE);
+  vty_out (vty, "%s+-%s [%d]%s", prefix, v->name, v->cost, VNL);
 
   len = strlen (prefix) + 4;
   next_prefix = (char *) malloc (len);
   if (next_prefix == NULL)
     {
-      vty_out (vty, "malloc failed%s", VTY_NEWLINE);
+      vty_out (vty, "malloc failed%s", VNL);
       return;
     }
   snprintf (next_prefix, len, "%s%s", prefix, (rest ? "|  " : "   "));
@@ -617,9 +617,9 @@ int
 config_write_ospf6_debug_spf (struct vty *vty)
 {
   if (IS_OSPF6_DEBUG_SPF (DETAIL))
-    vty_out (vty, "debug ospf6 spf detail%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 spf detail%s", VNL);
   else if (IS_OSPF6_DEBUG_SPF (SUMMARY))
-    vty_out (vty, "debug ospf6 spf%s", VTY_NEWLINE);
+    vty_out (vty, "debug ospf6 spf%s", VNL);
   return 0;
 }
 

+ 37 - 19
ospf6d/ospf6_top.c

@@ -30,7 +30,6 @@
 #include "thread.h"
 #include "command.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_message.h"
 #include "ospf6_lsa.h"
@@ -44,6 +43,8 @@
 #include "ospf6_neighbor.h"
 
 #include "ospf6_asbr.h"
+#include "ospf6_abr.h"
+#include "ospf6d.h"
 
 /* global ospf6d variable */
 struct ospf6 *ospf6;
@@ -80,6 +81,20 @@ ospf6_top_lsdb_hook_remove (struct ospf6_lsa *lsa)
     }
 }
 
+void
+ospf6_top_route_hook_add (struct ospf6_route *route)
+{
+  ospf6_abr_originate_prefix (route, ospf6);
+  ospf6_zebra_route_update_add (route);
+}
+
+void
+ospf6_top_route_hook_remove (struct ospf6_route *route)
+{
+  ospf6_abr_originate_prefix (route, ospf6);
+  ospf6_zebra_route_update_remove (route);
+}
+
 struct ospf6 *
 ospf6_create ()
 {
@@ -97,13 +112,15 @@ ospf6_create ()
   o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
 
   o->route_table = ospf6_route_table_create ();
-  o->route_table->hook_add = ospf6_zebra_route_update_add;
-  o->route_table->hook_remove = ospf6_zebra_route_update_remove;
+  o->route_table->hook_add = ospf6_top_route_hook_add;
+  o->route_table->hook_remove = ospf6_top_route_hook_remove;
 
   o->asbr_table = ospf6_route_table_create ();
   o->asbr_table->hook_add = ospf6_asbr_lsentry_add;
   o->asbr_table->hook_remove = ospf6_asbr_lsentry_remove;
 
+  o->brouter_table = ospf6_route_table_create ();
+
   o->external_table = ospf6_route_table_create ();
   o->external_id_table = route_table_init ();
 
@@ -126,6 +143,7 @@ ospf6_delete (struct ospf6 *o)
 
   ospf6_route_table_delete (o->route_table);
   ospf6_route_table_delete (o->asbr_table);
+  ospf6_route_table_delete (o->brouter_table);
 
   ospf6_route_table_delete (o->external_table);
   route_table_finish (o->external_id_table);
@@ -257,7 +275,7 @@ DEFUN (no_router_ospf6,
        OSPF6_ROUTER_STR)
 {
   if (ospf6 == NULL || CHECK_FLAG (ospf6->flag, OSPF6_DISABLED))
-    vty_out (vty, "OSPFv3 is not running%s", VTY_NEWLINE);
+    vty_out (vty, "OSPFv3 is not running%s", VNL);
   else
     ospf6_disable (ospf6);
 
@@ -284,7 +302,7 @@ DEFUN (ospf6_router_id,
   ret = inet_pton (AF_INET, argv[0], &router_id);
   if (ret == 0)
     {
-      vty_out (vty, "malformed OSPF Router-ID: %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "malformed OSPF Router-ID: %s%s", argv[0], VNL);
       return CMD_SUCCESS;
     }
 
@@ -317,14 +335,14 @@ DEFUN (ospf6_interface_area,
   if (oi->area)
     {
       vty_out (vty, "%s already attached to Area %s%s",
-               oi->interface->name, oi->area->name, VTY_NEWLINE);
+               oi->interface->name, oi->area->name, VNL);
       return CMD_SUCCESS;
     }
 
   /* parse Area-ID */
   if (inet_pton (AF_INET, argv[1], &area_id) != 1)
     {
-      vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VTY_NEWLINE);
+      vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
       return CMD_SUCCESS;
     }
 
@@ -362,28 +380,28 @@ DEFUN (no_ospf6_interface_area,
   ifp = if_lookup_by_name (argv[0]);
   if (ifp == NULL)
     {
-      vty_out (vty, "No such interface %s%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "No such interface %s%s", argv[0], VNL);
       return CMD_SUCCESS;
     }
 
   oi = (struct ospf6_interface *) ifp->info;
   if (oi == NULL)
     {
-      vty_out (vty, "Interface %s not enabled%s", ifp->name, VTY_NEWLINE);
+      vty_out (vty, "Interface %s not enabled%s", ifp->name, VNL);
       return CMD_SUCCESS;
     }
 
   /* parse Area-ID */
   if (inet_pton (AF_INET, argv[1], &area_id) != 1)
     {
-      vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VTY_NEWLINE);
+      vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
       return CMD_SUCCESS;
     }
 
   if (oi->area->area_id != area_id)
     {
       vty_out (vty, "Wrong Area-ID: %s is attached to area %s%s",
-               oi->interface->name, oi->area->name, VTY_NEWLINE);
+               oi->interface->name, oi->area->name, VNL);
       return CMD_SUCCESS;
     }
 
@@ -406,24 +424,24 @@ ospf6_show (struct vty *vty, struct ospf6 *o)
   /* process id, router id */
   inet_ntop (AF_INET, &o->router_id, router_id, sizeof (router_id));
   vty_out (vty, " OSPFv3 Routing Process (0) with Router-ID %s%s",
-           router_id, VTY_NEWLINE);
+           router_id, VNL);
 
   /* running time */
   gettimeofday (&now, (struct timezone *)NULL);
   timersub (&now, &o->starttime, &running);
   timerstring (&running, duration, sizeof (duration));
-  vty_out (vty, " Running %s%s", duration, VTY_NEWLINE);
+  vty_out (vty, " Running %s%s", duration, VNL);
 
   /* Redistribute configuration */
   /* XXX */
 
   /* LSAs */
   vty_out (vty, " Number of AS scoped LSAs is %u%s",
-           o->lsdb->count, VTY_NEWLINE);
+           o->lsdb->count, VNL);
 
   /* Areas */
   vty_out (vty, " Number of areas in this router is %u%s",
-           listcount (o->area_list), VTY_NEWLINE);
+           listcount (o->area_list), VNL);
   for (n = listhead (o->area_list); n; nextnode (n))
     {
       oa = (struct ospf6_area *) getdata (n);
@@ -540,8 +558,8 @@ config_write_ospf6 (struct vty *vty)
     return CMD_SUCCESS;
 
   inet_ntop (AF_INET, &ospf6->router_id, router_id, sizeof (router_id));
-  vty_out (vty, "router ospf6%s", VTY_NEWLINE);
-  vty_out (vty, " router-id %s%s", router_id, VTY_NEWLINE);
+  vty_out (vty, "router ospf6%s", VNL);
+  vty_out (vty, " router-id %s%s", router_id, VNL);
 
   ospf6_redistribute_config_write (vty);
 
@@ -552,10 +570,10 @@ config_write_ospf6 (struct vty *vty)
         {
           oi = (struct ospf6_interface *) getdata (k);
           vty_out (vty, " interface %s area %s%s",
-                   oi->interface->name, oa->name, VTY_NEWLINE);
+                   oi->interface->name, oa->name, VNL);
         }
     }
-  vty_out (vty, "!%s", VTY_NEWLINE);
+  vty_out (vty, "!%s", VNL);
   return 0;
 }
 

+ 1 - 0
ospf6d/ospf6_top.h

@@ -41,6 +41,7 @@ struct ospf6
 
   struct ospf6_route_table *route_table;
   struct ospf6_route_table *asbr_table;
+  struct ospf6_route_table *brouter_table;
 
   struct ospf6_route_table *external_table;
   struct route_table *external_id_table;

+ 15 - 14
ospf6d/ospf6_zebra.c

@@ -29,14 +29,15 @@
 #include "zclient.h"
 #include "memory.h"
 
-#include "ospf6d.h"
 #include "ospf6_proto.h"
 #include "ospf6_top.h"
 #include "ospf6_interface.h"
 #include "ospf6_route.h"
 #include "ospf6_lsa.h"
+#include "ospf6_lsdb.h"
 #include "ospf6_asbr.h"
 #include "ospf6_zebra.h"
+#include "ospf6d.h"
 
 unsigned char conf_debug_ospf6_zebra = 0;
 
@@ -251,22 +252,22 @@ DEFUN (show_zebra,
   int i;
   if (zclient == NULL)
     {
-      vty_out (vty, "Not connected to zebra%s", VTY_NEWLINE);
+      vty_out (vty, "Not connected to zebra%s", VNL);
       return CMD_SUCCESS;
     }
 
-  vty_out (vty, "Zebra Infomation%s", VTY_NEWLINE);
+  vty_out (vty, "Zebra Infomation%s", VNL);
   vty_out (vty, "  enable: %d fail: %d%s",
-           zclient->enable, zclient->fail, VTY_NEWLINE);
+           zclient->enable, zclient->fail, VNL);
   vty_out (vty, "  redistribute default: %d%s", zclient->redist_default,