* isis_lsp.h: Added backpointer to the area from LSP. For now it's used
	  only in generated topology LSPs.
	* isisd.[ch]: Cleanup CLI commands related to topology generation and
	  added command to specify base fo dynamic hostname for topology LSPs.
	* isis_lsp.c: Rewrite almost all code related to generation topology
	  LSPs (top_lsp_refresh(), generate_topology_lsps() and
	  build_topology_lsp_data() functions). Topology is connected to own
	  LSP now (lsp_build_nonpseudo). Commented out lsppdu_realloc
	  functions, it's not used any more hopefully.

	Topology generation feature is actually useful now.
diff --git a/isisd/ChangeLog b/isisd/ChangeLog
index d9e65bb..c245d09 100644
--- a/isisd/ChangeLog
+++ b/isisd/ChangeLog
@@ -1,3 +1,15 @@
+2005-09-19 Hasso Tepper <hasso at quagga.net>
+
+	* isis_lsp.h: Added backpointer to the area from LSP. For now it's used
+	  only in generated topology LSPs.
+	* isisd.[ch]: Cleanup CLI commands related to topology generation and
+	  added command to specify base fo dynamic hostname for topology LSPs.
+	* isis_lsp.c: Rewrite almost all code related to generation topology
+	  LSPs (top_lsp_refresh(), generate_topology_lsps() and
+	  build_topology_lsp_data() functions). Topology is connected to own
+	  LSP now (lsp_build_nonpseudo). Commented out lsppdu_realloc
+	  functions, it's not used any more hopefully.
+
 2005-09-18 Hasso Tepper <hasso at quagga.net>
 
 	* isis_lsp.c (lsp_update): Fix previous commit - manipulate the right
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index a294bc8..26c46a2 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -914,6 +914,7 @@
   return lsp_count;
 }
 
+#if 0
 /* this function reallocate memory to an lsp pdu, with an additional
  * size of memory, it scans the lsp and moves all pointers the
  * way they should */
@@ -939,6 +940,7 @@
   return STREAM_DATA (lsp->pdu) + (lsp->lsp_header->pdu_len - size);
 #endif /* LSP_MEMORY_PREASSIGN */
 }
+#endif
 
 #if 0				/* Saving the old one just in case :) */
 /*
@@ -1356,6 +1358,28 @@
       add_tlv (IPV4_ADDR, IPV4_MAX_BYTELEN, (u_char *) &routerid->s_addr,
 	       lsp->pdu);
     }
+
+#ifdef TOPOLOGY_GENERATE
+  /* If topology exists (and we create topology for level 1 only), create
+   * (hardcoded) link to topology. */
+  if (area->topology && level == 1)
+    {
+      if (tlv_data.is_neighs == NULL)
+        tlv_data.is_neighs = list_new ();
+      is_neigh = XMALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
+      memset (is_neigh, 0, sizeof (struct is_neigh));
+
+      memcpy (&is_neigh->neigh_id, area->topology_baseis, ISIS_SYS_ID_LEN);
+      is_neigh->neigh_id[ISIS_SYS_ID_LEN - 1] = (1 & 0xFF);
+      is_neigh->neigh_id[ISIS_SYS_ID_LEN - 2] = ((1 >> 8) & 0xFF);
+      is_neigh->metrics.metric_default = 0x01;
+      is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED;
+      is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED;
+      is_neigh->metrics.metric_error = METRICS_UNSUPPORTED;
+      listnode_add (tlv_data.is_neighs, is_neigh);
+    }
+#endif /* TOPOLOGY_GENERATE */
+
   /*
    * Then build lists of tlvs related to circuits
    */
@@ -2156,7 +2180,10 @@
 			      lsp->level,
 			      rawlspid_print (lsp->lsp_header->lsp_id),
 			      ntohl (lsp->lsp_header->seq_num));
-
+#ifdef TOPOLOGY_GENERATE
+		  if (lsp->from_topology)
+		    THREAD_TIMER_OFF (lsp->t_lsp_top_ref);
+#endif /* TOPOLOGY_GENERATE */
 		  lsp_destroy (lsp);
 		  dict_delete (area->lspdb[level], dnode);
 		}
@@ -2266,15 +2293,14 @@
 top_lsp_refresh (struct thread *thread)
 {
   struct isis_lsp *lsp;
+  unsigned long ref_time;
 
   lsp = THREAD_ARG (thread);
   assert (lsp);
 
   lsp->t_lsp_top_ref = NULL;
 
-  lsp->lsp_header->rem_lifetime =
-    htons (isis_jitter (MAX_AGE, MAX_AGE_JITTER));
-  lsp->lsp_header->seq_num = htonl (ntohl (lsp->lsp_header->seq_num) + 1);
+  lsp_seqnum_update (lsp);
 
   ISIS_FLAGS_SET_ALL (lsp->SRMflags);
   if (isis->debugs & DEBUG_UPDATE_PACKETS)
@@ -2282,12 +2308,14 @@
       zlog_debug ("ISIS-Upd (): refreshing Topology L1 %s",
 		  rawlspid_print (lsp->lsp_header->lsp_id));
     }
+  lsp->lsp_header->rem_lifetime =
+    htons (isis_jitter (lsp->area->max_lsp_lifetime[0], MAX_AGE_JITTER));
 
-  /* time to calculate our checksum */
-  iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
-		   ntohs (lsp->lsp_header->pdu_len) - 12, 12);
+  ref_time = lsp->area->lsp_refresh[0] > MAX_LSP_GEN_INTERVAL ?
+    MAX_LSP_GEN_INTERVAL : lsp->area->lsp_refresh[0];
+
   THREAD_TIMER_ON (master, lsp->t_lsp_top_ref, top_lsp_refresh, lsp,
-		   isis_jitter (MAX_LSP_GEN_INTERVAL, MAX_LSP_GEN_JITTER));
+		   isis_jitter (ref_time, MAX_LSP_GEN_JITTER));
 
   return ISIS_OK;
 }
@@ -2300,6 +2328,7 @@
   struct arc *arc;
   u_char lspid[ISIS_SYS_ID_LEN + 2];
   struct isis_lsp *lsp;
+  unsigned long ref_time;
 
   /* first we find the maximal node */
   for (ALL_LIST_ELEMENTS_RO (area->topology, node, arc))
@@ -2319,21 +2348,24 @@
       lspid[ISIS_SYS_ID_LEN - 2] = ((i >> 8) & 0xFF);
 
       lsp = lsp_new (lspid, isis_jitter (area->max_lsp_lifetime[0],
-					 MAX_AGE_JITTER), 1, IS_LEVEL_1, 0,
-		     1);
+		     MAX_AGE_JITTER), 1, IS_LEVEL_1, 0, 1);
+      if (!lsp)
+	return;
       lsp->from_topology = 1;
-      /* creating data based on topology */
-      build_topology_lsp_data (lsp, area, i);
-      /* time to calculate our checksum */
-      iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
-		       ntohs (lsp->lsp_header->pdu_len) - 12, 12);
-      THREAD_TIMER_ON (master, lsp->t_lsp_top_ref, top_lsp_refresh, lsp,
-		       isis_jitter (MAX_LSP_GEN_INTERVAL,
-				    MAX_LSP_GEN_JITTER));
+      lsp->area = area;
 
+      /* Creating LSP data based on topology info. */
+      build_topology_lsp_data (lsp, area, i);
+      /* Checksum is also calculated here. */
+      lsp_seqnum_update (lsp);
+
+      ref_time = area->lsp_refresh[0] > MAX_LSP_GEN_INTERVAL ?
+	MAX_LSP_GEN_INTERVAL : area->lsp_refresh[0];
+
+      THREAD_TIMER_ON (master, lsp->t_lsp_top_ref, top_lsp_refresh, lsp,
+		       isis_jitter (ref_time, MAX_LSP_GEN_JITTER));
       ISIS_FLAGS_SET_ALL (lsp->SRMflags);
       lsp_insert (lsp, area->lspdb[0]);
-
     }
 }
 
@@ -2364,100 +2396,99 @@
 {
   struct listnode *node, *nnode;
   struct arc *arc;
-  u_char *tlv_ptr;
   struct is_neigh *is_neigh;
-  int to_lsp = 0;
   char buff[200];
+  struct tlvs tlv_data;
+  struct isis_lsp *lsp0 = lsp;
 
-  /* add our nlpids */
-  /* the 2 is for the TL plus 1 for the nlpid */
-  tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 3);
-  *tlv_ptr = PROTOCOLS_SUPPORTED;	/* Type */
-  *(tlv_ptr + 1) = 1;		/* one protocol */
-  *(tlv_ptr + 2) = NLPID_IP;
-  lsp->tlv_data.nlpids = (struct nlpids *) (tlv_ptr + 1);
+  /* Add area addresses. FIXME: Is it needed at all? */
+  if (lsp->tlv_data.area_addrs == NULL)
+    lsp->tlv_data.area_addrs = list_new ();
+  list_add_list (lsp->tlv_data.area_addrs, area->area_addrs);
 
-  /* first, lets add the tops */
-  /* the 2 is for the TL plus 1 for the virtual field */
-  tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 3);
-  *tlv_ptr = IS_NEIGHBOURS;	/* Type */
-  *(tlv_ptr + 1) = 1;		/* this is the virtual char len */
-  *(tlv_ptr + 2) = 0;		/* virtual is zero */
-  lsp->tlv_data.is_neighs = list_new ();	/* new list of is_neighbours */
+  if (lsp->tlv_data.nlpids == NULL)
+    lsp->tlv_data.nlpids = XMALLOC (MTYPE_ISIS_TLV, sizeof (struct nlpids));
+  lsp->tlv_data.nlpids->count = 1;
+  lsp->tlv_data.nlpids->nlpids[0] = NLPID_IP;
 
-  /* add reachability for this IS for simulated 1 */
+  if (area->dynhostname)
+    {
+      lsp->tlv_data.hostname = XMALLOC (MTYPE_ISIS_TLV,
+					sizeof (struct hostname));
+      memset (buff, 0x00, 200);
+      sprintf (buff, "%s%d", area->topology_basedynh ? area->topology_basedynh :
+	       "feedme", lsp_top_num);
+      memcpy (lsp->tlv_data.hostname->name, buff, strlen (buff));
+      lsp->tlv_data.hostname->namelen = strlen (buff);
+    }
+
+  if (lsp->tlv_data.nlpids)
+    tlv_add_nlpid (lsp->tlv_data.nlpids, lsp->pdu);
+  if (lsp->tlv_data.hostname)
+    tlv_add_dynamic_hostname (lsp->tlv_data.hostname, lsp->pdu);
+  if (lsp->tlv_data.area_addrs && listcount (lsp->tlv_data.area_addrs) > 0)
+    tlv_add_area_addrs (lsp->tlv_data.area_addrs, lsp->pdu);
+
+  memset (&tlv_data, 0, sizeof (struct tlvs));
+  if (tlv_data.is_neighs == NULL)
+    tlv_data.is_neighs = list_new ();
+
+  /* Add reachability for this IS for simulated 1. */
   if (lsp_top_num == 1)
     {
-      /* assign space for the is_neigh at the pdu end */
-      is_neigh = (struct is_neigh *) lsppdu_realloc (lsp, MTYPE_ISIS_TLV,
-						     sizeof (struct
-							     is_neigh));
-      /* add this node to our list */
-      listnode_add (lsp->tlv_data.is_neighs, is_neigh);
+      is_neigh = XMALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
+      memset (is_neigh, 0, sizeof (struct is_neigh));
+
       memcpy (&is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN);
       LSP_PSEUDO_ID (is_neigh->neigh_id) = 0x00;
-      is_neigh->metrics.metric_default = 0x00;	/* no special reason */
+      /* Metric MUST NOT be 0, unless it's not alias TLV. */
+      is_neigh->metrics.metric_default = 0x01;
       is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED;
       is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED;
       is_neigh->metrics.metric_error = METRICS_UNSUPPORTED;
-      /* don't forget the length */
-      *(tlv_ptr + 1) += IS_NEIGHBOURS_LEN;	/* the -1 is the virtual */
-      /* no need to check for fragging here, it is a lonely is_reach */
+      listnode_add (tlv_data.is_neighs, is_neigh);
     }
 
-  /* addding is reachabilities */
+  /* Add IS reachabilities. */
   for (ALL_LIST_ELEMENTS (area->topology, node, nnode, arc))
-  {
-    if ((arc->from_node == lsp_top_num) || (arc->to_node == lsp_top_num))
-      {
-	if (arc->to_node == lsp_top_num)
-	  to_lsp = arc->from_node;
-	if (arc->from_node == lsp_top_num)
-	  to_lsp = arc->to_node;
-
-	/* if the length here is about to cross the FF limit, we reTLV */
-	if (*(tlv_ptr + 1) >= (0xFF - IS_NEIGHBOURS_LEN))
-	  {
-	    /* retlv */
-	    /* the 2 is for the TL plus 1 for the virtual field */
-	    tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 3);
-	    *tlv_ptr = IS_NEIGHBOURS;	/* Type */
-	    *(tlv_ptr + 1) = 1;	/* this is the virtual char len */
-	    *(tlv_ptr + 2) = 0;	/* virtual is zero */
-	  }
-	/* doing this here assures us that we won't add an "empty" tlv */
-	/* assign space for the is_neigh at the pdu end */
-	is_neigh = (struct is_neigh *) lsppdu_realloc (lsp, MTYPE_ISIS_TLV,
-						       sizeof (struct
-							       is_neigh));
-	/* add this node to our list */
-	listnode_add (lsp->tlv_data.is_neighs, is_neigh);
-	memcpy (&is_neigh->neigh_id, area->topology_baseis, ISIS_SYS_ID_LEN);
-	LSP_PSEUDO_ID (is_neigh->neigh_id) = 0x00;
-	is_neigh->neigh_id[ISIS_SYS_ID_LEN - 1] = (to_lsp & 0xFF);
-	is_neigh->neigh_id[ISIS_SYS_ID_LEN - 2] = ((to_lsp >> 8) & 0xFF);
-	is_neigh->metrics.metric_default = arc->distance;
-	is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED;
-	is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED;
-	is_neigh->metrics.metric_error = METRICS_UNSUPPORTED;
-	/* don't forget the length */
-	*(tlv_ptr + 1) += IS_NEIGHBOURS_LEN;	/* the -1 is the virtual */
-      }
-  }
-
-  /* adding dynamic hostname if needed */
-  if (area->dynhostname)
     {
-      memset (buff, 0x00, 200);
-      sprintf (buff, "feedme%d", lsp_top_num);
-      /* the 2 is for the TL */
-      tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 2);
-      *tlv_ptr = DYNAMIC_HOSTNAME;	/* Type */
-      *(tlv_ptr + 1) = strlen (buff);	/* Length */
-      /* the -1 is to fit the length in the struct */
-      lsp->tlv_data.hostname = (struct hostname *)
-	(lsppdu_realloc (lsp, MTYPE_ISIS_TLV, strlen (buff)) - 1);
-      memcpy (lsp->tlv_data.hostname->name, buff, strlen (buff));
+      int to_lsp = 0;
+      
+      if ((lsp_top_num != arc->from_node) && (lsp_top_num != arc->to_node))
+	continue;
+
+      if (lsp_top_num == arc->from_node)
+	to_lsp = arc->to_node;
+      else
+	to_lsp = arc->from_node;
+
+      is_neigh = XMALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
+      memset (is_neigh, 0, sizeof (struct is_neigh));
+
+      memcpy (&is_neigh->neigh_id, area->topology_baseis, ISIS_SYS_ID_LEN);
+      is_neigh->neigh_id[ISIS_SYS_ID_LEN - 1] = (to_lsp & 0xFF);
+      is_neigh->neigh_id[ISIS_SYS_ID_LEN - 2] = ((to_lsp >> 8) & 0xFF);
+      is_neigh->metrics.metric_default = arc->distance;
+      is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED;
+      is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED;
+      is_neigh->metrics.metric_error = METRICS_UNSUPPORTED;
+      listnode_add (tlv_data.is_neighs, is_neigh);
     }
+
+  while (tlv_data.is_neighs && listcount (tlv_data.is_neighs))
+    {
+      if (lsp->tlv_data.is_neighs == NULL)
+	lsp->tlv_data.is_neighs = list_new ();
+      lsp_tlv_fit (lsp, &tlv_data.is_neighs,
+		   &lsp->tlv_data.is_neighs,
+		   IS_NEIGHBOURS_LEN, area->lsp_frag_threshold,
+		   tlv_add_is_neighs);
+      if (tlv_data.is_neighs && listcount (tlv_data.is_neighs))
+        lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
+			     lsp0, area, IS_LEVEL_1);
+    }
+
+  free_tlvs (&tlv_data);
+  return;
 }
 #endif /* TOPOLOGY_GENERATE */
diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h
index fb6f1d8..adbde78 100644
--- a/isisd/isis_lsp.h
+++ b/isisd/isis_lsp.h
@@ -59,6 +59,8 @@
   /* used for 60 second counting when rem_lifetime is zero */
   int age_out;
   struct isis_adjacency *adj;
+  /* FIXME: For now only topology LSP's use this. Is it helpful for others? */
+  struct isis_area *area;
   struct tlvs tlv_data;		/* Simplifies TLV access */
 };
 
diff --git a/isisd/isisd.c b/isisd/isisd.c
index a8d6950..1f0167b 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -20,7 +20,6 @@
  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-#include <string.h>
 #include <zebra.h>
 
 #include "thread.h"
@@ -856,7 +855,7 @@
        "debug isis events",
        DEBUG_STR
        "IS-IS information\n"
-       "IS-IS  Events\n")
+       "IS-IS Events\n")
 {
   isis->debugs |= DEBUG_EVENTS;
   print_debug (vty, DEBUG_EVENTS, 1);
@@ -1555,9 +1554,9 @@
        topology_generate_grid_cmd,
        "topology generate grid <1-100> <1-100> <1-65000> [param] [param] "
        "[param]",
-       "Topology for IS-IS\n"
-       "Topology for IS-IS\n"
-       "Topology grid for IS-IS\n"
+       "Topology generation for IS-IS\n"
+       "Topology generation\n"
+       "Grid topology\n"
        "X parameter of the grid\n"
        "Y parameter of the grid\n"
        "Random seed\n"
@@ -1580,6 +1579,9 @@
       gen_spgrid_topology (vty, area->topology);
       remove_topology_lsps (area);
       generate_topology_lsps (area);
+      /* Regenerate L1 LSP to get two way connection to the generated
+       * topology. */
+      lsp_regenerate_schedule (area);
     }
 
   return CMD_SUCCESS;
@@ -1587,41 +1589,39 @@
 
 DEFUN (show_isis_generated_topology,
        show_isis_generated_topology_cmd,
-       "show isis generated-topology",
+       "show isis generated-topologies",
        SHOW_STR
-       "clns network information\n"
-       "CLNS neighbor adjacencies\n")
+       "CLNS network information\n"
+       "Show generated topologies\n")
 {
   struct isis_area *area;
   struct listnode *node;
   struct listnode *node2;
   struct arc *arc;
+
   for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
-  {
-    if (area->topology)
-      {
-	vty_out (vty, "Topology for isis area:%s%s", area->area_tag,
-		 VTY_NEWLINE);
-	for (ALL_LIST_ELEMENTS_RO (area->topology, node2, arc))
-	{
-	  vty_out (vty, "a  %ld   %ld   %ld%s", arc->from_node, arc->to_node,
-		   arc->distance, VTY_NEWLINE);
-	}
-      }
-  }
+    {
+      if (!area->topology)
+	continue;
+
+      vty_out (vty, "Topology for isis area: %s%s", area->area_tag,
+	       VTY_NEWLINE);
+      vty_out (vty, "From node     To node     Distance%s", VTY_NEWLINE);
+
+      for (ALL_LIST_ELEMENTS_RO (area->topology, node2, arc))
+	vty_out (vty, "%9ld %11ld %12ld%s", arc->from_node, arc->to_node,
+		 arc->distance, VTY_NEWLINE);
+    }
   return CMD_SUCCESS;
 }
 
-/*
- * 'topology base-is' command
- */
+/* Base IS for topology generation. */
 DEFUN (topology_baseis,
        topology_baseis_cmd,
        "topology base-is WORD",
-       "Topology for IS-IS\n"
-       "Topology for IS-IS\n"
-       "A Network IS Base for this topology"
-       "XX.XXXX.XXXX.XX Network entity title (NET)\n")
+       "Topology generation for IS-IS\n"
+       "A Network IS Base for this topology\n"
+       "XXXX.XXXX.XXXX Network entity title (NET)\n")
 {
   struct isis_area *area;
   u_char buff[ISIS_SYS_ID_LEN];
@@ -1630,22 +1630,18 @@
   assert (area);
 
   if (sysid2buff (buff, argv[0]))
-    {
-      sysid2buff (area->topology_baseis, argv[0]);
-    }
+    sysid2buff (area->topology_baseis, argv[0]);
 
   return CMD_SUCCESS;
 }
 
-/*
- * 'no net' command
- */
 DEFUN (no_topology_baseis,
        no_topology_baseis_cmd,
        "no topology base-is WORD",
        NO_STR
-       "A Network Entity Title for this process (OSI only)"
-       "XX.XXXX. ... .XXX.XX  Network entity title (NET)\n")
+       "Topology generation for IS-IS\n"
+       "A Network IS Base for this topology\n"
+       "XXXX.XXXX.XXXX Network entity title (NET)\n")
 {
   struct isis_area *area;
 
@@ -1656,6 +1652,29 @@
   return CMD_SUCCESS;
 }
 
+ALIAS (no_topology_baseis,
+       no_topology_baseis_noid_cmd,
+       "no topology base-is",
+       NO_STR
+       "Topology generation for IS-IS\n"
+       "A Network IS Base for this topology\n")
+
+DEFUN (topology_basedynh,
+       topology_basedynh_cmd,
+       "topology base-dynh WORD",
+       "Topology generation for IS-IS\n"
+       "Dynamic hostname base for this topology\n"
+       "Dynamic hostname base\n")
+{
+  struct isis_area *area;
+
+  area = vty->index;
+  assert (area);
+
+  /* I hope that it's enough. */
+  area->topology_basedynh = strndup (argv[0], 16); 
+  return CMD_SUCCESS;
+}
 #endif /* TOPOLOGY_GENERATE */
 
 DEFUN (lsp_lifetime,
@@ -1968,23 +1987,29 @@
 	    vty_out(vty, "%s", VTY_NEWLINE);
 	    write++;
 	  }
+
 #ifdef TOPOLOGY_GENERATE
-	/* seems we save the whole command line here */
-	if (area->top_params)
+	if (memcmp (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS,
+		    ISIS_SYS_ID_LEN))
+	  {
+	    vty_out (vty, " topology base-is %s%s",
+		     sysid_print (area->topology_baseis), VTY_NEWLINE);
+	    write++;
+	  }
+	if (area->topology_basedynh)
+	  {
+	    vty_out (vty, " topology base-dynh %s%s",
+		     area->topology_basedynh, VTY_NEWLINE);
+	    write++;
+	  }
+	/* We save the whole command line here. */
+	if (strlen(area->top_params))
 	  {
 	    vty_out (vty, " %s%s", area->top_params, VTY_NEWLINE);
 	    write++;
 	  }
-
-	if (memcmp (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS,
-		    ISIS_SYS_ID_LEN))
-	  {
-	    vty_out (vty, " topology base_is %s%s",
-		     sysid_print (area->topology_baseis), VTY_NEWLINE);
-	    write++;
-	  }
-
 #endif /* TOPOLOGY_GENERATE */
+
       }
     }
 
@@ -2127,7 +2152,9 @@
 #ifdef TOPOLOGY_GENERATE
   install_element (ISIS_NODE, &topology_generate_grid_cmd);
   install_element (ISIS_NODE, &topology_baseis_cmd);
+  install_element (ISIS_NODE, &topology_basedynh_cmd);
   install_element (ISIS_NODE, &no_topology_baseis_cmd);
+  install_element (ISIS_NODE, &no_topology_baseis_noid_cmd);
   install_element (VIEW_NODE, &show_isis_generated_topology_cmd);
   install_element (ENABLE_NODE, &show_isis_generated_topology_cmd);
 #endif /* TOPOLOGY_GENERATE */
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 7a9f764..e66f60e 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -123,11 +123,13 @@
 #endif				/* HAVE_IPV6 */
   /* Counters */
   u_int32_t circuit_state_changes;
+
 #ifdef TOPOLOGY_GENERATE
   struct list *topology;
-  char topology_baseis[ISIS_SYS_ID_LEN];	/* is for the first is emulated  */
-  char top_params[200];		/* FIXME: what is reasonable?    */
-#endif				/* TOPOLOGY_GENERATE */
+  char topology_baseis[ISIS_SYS_ID_LEN];  /* IS for the first IS emulated. */
+  char *topology_basedynh;                /* Dynamic hostname base. */
+  char top_params[200];                   /* FIXME: what is reasonable? */
+#endif /* TOPOLOGY_GENERATE */
 };
 
 void isis_init (void);