Merge isisd into the Quagga's framework:
  - add privs support
  - use misc quagga's definitions
  - make it compile"able"
  - fix segfault cases related to hostname()
  - add debug isis xxx command

This patch has been approved by Paul Jakma.
diff --git a/lib/command.c b/lib/command.c
index 43a0bb3..2411306 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -2325,6 +2325,7 @@
     case RIPNG_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
+    case ISIS_NODE:
     case KEYCHAIN_NODE:
     case MASC_NODE:
     case RMAP_NODE:
@@ -2377,6 +2378,7 @@
     case RMAP_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
+    case ISIS_NODE:
     case KEYCHAIN_NODE:
     case KEYCHAIN_KEY_NODE:
     case MASC_NODE:
diff --git a/lib/command.h b/lib/command.h
index 3009b26..32a347f 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -87,6 +87,7 @@
   BGP_IPV6_NODE,		/* BGP IPv6 address family */
   OSPF_NODE,			/* OSPF protocol mode */
   OSPF6_NODE,			/* OSPF protocol for IPv6 mode */
+  ISIS_NODE,			/* ISIS protocol mode */
   MASC_NODE,			/* MASC for multicast.  */
   IRDP_NODE,			/* ICMP Router Discovery Protocol mode. */ 
   IP_NODE,			/* Static ip route node. */
@@ -255,6 +256,8 @@
 #define PREFIX_LIST_STR "Build a prefix list\n"
 #define OSPF6_DUMP_TYPE_LIST \
 "(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
+#define ISIS_STR "IS-IS information\n"
+#define AREA_TAG_STR "[area tag]\n"
 
 #define CONF_BACKUP_EXT ".sav"
 
diff --git a/lib/log.c b/lib/log.c
index aedab3c..5f6b32f 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -37,6 +37,7 @@
   "OSPF",
   "RIPNG",
   "OSPF6",
+  "ISIS",
   "MASC",
   NULL,
 };
diff --git a/lib/log.h b/lib/log.h
index 69919b4..8948ea0 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -47,6 +47,7 @@
   ZLOG_OSPF,
   ZLOG_RIPNG,  
   ZLOG_OSPF6,
+  ZLOG_ISIS,
   ZLOG_MASC
 } zlog_proto_t;
 
diff --git a/lib/memory.c b/lib/memory.c
index 9383311..faf3f26 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -385,6 +385,25 @@
   { -1, NULL },
 };
 
+struct memory_list memory_list_isis[] =
+{
+  { MTYPE_ISIS,               "ISIS              " },
+  { MTYPE_ISIS_TMP,           "ISIS TMP          " },
+  { MTYPE_ISIS_CIRCUIT,       "ISIS circuit      " },
+  { MTYPE_ISIS_LSP,           "ISIS LSP          " },
+  { MTYPE_ISIS_ADJACENCY,     "ISIS adjacency    " },
+  { MTYPE_ISIS_AREA,          "ISIS area         " },
+  { MTYPE_ISIS_AREA_ADDR,     "ISIS area address " },
+  { MTYPE_ISIS_TLV,           "ISIS TLV          " },
+  { MTYPE_ISIS_DYNHN,         "ISIS dyn hostname " },
+  { MTYPE_ISIS_SPFTREE,       "ISIS SPFtree      " },
+  { MTYPE_ISIS_VERTEX,        "ISIS vertex       " },
+  { MTYPE_ISIS_ROUTE_INFO,    "ISIS route info   " },
+  { MTYPE_ISIS_NEXTHOP,       "ISIS nexthop      " },
+  { MTYPE_ISIS_NEXTHOP6,      "ISIS nexthop6     " },
+  { -1, NULL },
+};
+
 struct memory_list memory_list_separator[] =
 {
   { 0, NULL},
@@ -420,6 +439,8 @@
   show_memory_vty (vty, memory_list_separator);
   show_memory_vty (vty, memory_list_ospf6);
   show_memory_vty (vty, memory_list_separator);
+  show_memory_vty (vty, memory_list_isis);
+  show_memory_vty (vty, memory_list_separator);
   show_memory_vty (vty, memory_list_bgp);
 
   return CMD_SUCCESS;
@@ -497,6 +518,17 @@
   return CMD_SUCCESS;
 }
 
+DEFUN (show_memory_isis,
+       show_memory_isis_cmd,
+       "show memory isis",
+       SHOW_STR
+       "Memory statistics\n"
+       "ISIS memory\n")
+{
+  show_memory_vty (vty, memory_list_isis);
+  return CMD_SUCCESS;
+}
+
 void
 memory_init ()
 {
@@ -508,6 +540,7 @@
   install_element (VIEW_NODE, &show_memory_bgp_cmd);
   install_element (VIEW_NODE, &show_memory_ospf_cmd);
   install_element (VIEW_NODE, &show_memory_ospf6_cmd);
+  install_element (VIEW_NODE, &show_memory_isis_cmd);
 
   install_element (ENABLE_NODE, &show_memory_cmd);
   install_element (ENABLE_NODE, &show_memory_all_cmd);
@@ -517,4 +550,5 @@
   install_element (ENABLE_NODE, &show_memory_bgp_cmd);
   install_element (ENABLE_NODE, &show_memory_ospf_cmd);
   install_element (ENABLE_NODE, &show_memory_ospf6_cmd);
+  install_element (ENABLE_NODE, &show_memory_isis_cmd);
 }
diff --git a/lib/memory.h b/lib/memory.h
index 925f6b6..96b5f6c 100644
--- a/lib/memory.h
+++ b/lib/memory.h
@@ -126,6 +126,22 @@
   MTYPE_OSPF6_EXTERNAL_INFO,
   MTYPE_OSPF6_OTHER,
 
+  
+  MTYPE_ISIS,
+  MTYPE_ISIS_TMP,
+  MTYPE_ISIS_CIRCUIT,
+  MTYPE_ISIS_LSP,
+  MTYPE_ISIS_ADJACENCY,
+  MTYPE_ISIS_AREA,
+  MTYPE_ISIS_AREA_ADDR,
+  MTYPE_ISIS_TLV,
+  MTYPE_ISIS_DYNHN,
+  MTYPE_ISIS_SPFTREE,
+  MTYPE_ISIS_VERTEX,
+  MTYPE_ISIS_ROUTE_INFO,
+  MTYPE_ISIS_NEXTHOP,
+  MTYPE_ISIS_NEXTHOP6,
+
   MTYPE_BGP,
   MTYPE_BGP_PEER,
   MTYPE_PEER_GROUP,
diff --git a/lib/thread.c b/lib/thread.c
index 402167c..93809f2 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -518,6 +518,46 @@
   return thread;
 }
 
+/* Add timer event thread with "millisecond" resolution */
+struct thread *
+funcname_thread_add_timer_msec (struct thread_master *m,
+		  int (*func) (struct thread *), void *arg, long timer, char* funcname)
+{
+  struct timeval timer_now;
+  struct thread *thread;
+#ifndef TIMER_NO_SORT
+  struct thread *tt;
+#endif /* TIMER_NO_SORT */
+
+  assert (m != NULL);
+
+  thread = thread_get (m, THREAD_TIMER, func, arg, funcname);
+
+  timer = 1000*timer; /* milli -> micro */
+
+  /* Do we need jitter here? */
+  gettimeofday (&timer_now, NULL);
+  timer_now.tv_sec += timer / TIMER_SECOND_MICRO;
+  timer_now.tv_usec += (timer % TIMER_SECOND_MICRO);
+  thread->u.sands = timer_now;
+
+  /* Sort by timeval. */
+#ifdef TIMER_NO_SORT
+  thread_list_add (&m->timer, thread);
+#else
+  for (tt = m->timer.head; tt; tt = tt->next)
+    if (timeval_cmp (thread->u.sands, tt->u.sands) <= 0)
+      break;
+
+  if (tt)
+    thread_list_add_before (&m->timer, tt, thread);
+  else
+    thread_list_add (&m->timer, thread);
+#endif /* TIMER_NO_SORT */
+
+  return thread;
+}
+
 /* Add simple event thread. */
 struct thread *
 funcname_thread_add_event (struct thread_master *m,
diff --git a/lib/thread.h b/lib/thread.h
index 0a45d8f..9a8c2be 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -131,6 +131,7 @@
 #define thread_add_read(m,f,a,v) funcname_thread_add_read(m,f,a,v,#f)
 #define thread_add_write(m,f,a,v) funcname_thread_add_write(m,f,a,v,#f)
 #define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f)
+#define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f)
 #define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f)
 #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f)
 
@@ -142,6 +143,8 @@
 				 int (*)(struct thread *), void *, int, char*);
 struct thread *funcname_thread_add_timer (struct thread_master *,
 				 int (*)(struct thread *), void *, long, char*);
+struct thread *funcname_thread_add_timer_msec (struct thread_master *,
+				 int (*)(struct thread *), void *, long, char*);
 struct thread *funcname_thread_add_event (struct thread_master *,
 				 int (*)(struct thread *), void *, int, char*);
 void thread_cancel (struct thread *);
diff --git a/lib/vty.c b/lib/vty.c
index 6063290..2b823e0 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -626,6 +626,7 @@
     case RMAP_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
+    case ISIS_NODE:
     case KEYCHAIN_NODE:
     case KEYCHAIN_KEY_NODE:
     case MASC_NODE:
@@ -1030,6 +1031,7 @@
     case RMAP_NODE:
     case OSPF_NODE:
     case OSPF6_NODE:
+    case ISIS_NODE:
     case KEYCHAIN_NODE:
     case KEYCHAIN_KEY_NODE:
     case MASC_NODE:
diff --git a/lib/zebra.h b/lib/zebra.h
index 51bdc88..997237d 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -261,8 +261,9 @@
 #define ZEBRA_ROUTE_RIPNG                5
 #define ZEBRA_ROUTE_OSPF                 6
 #define ZEBRA_ROUTE_OSPF6                7
-#define ZEBRA_ROUTE_BGP                  8
-#define ZEBRA_ROUTE_MAX                  9
+#define ZEBRA_ROUTE_ISIS                 8
+#define ZEBRA_ROUTE_BGP                  9
+#define ZEBRA_ROUTE_MAX                  10
 
 /* Zebra's family types. */
 #define ZEBRA_FAMILY_IPV4                1
@@ -325,6 +326,7 @@
 #define ZEBRA_RIPNG_DISTANCE_DEFAULT     120
 #define ZEBRA_OSPF_DISTANCE_DEFAULT      110
 #define ZEBRA_OSPF6_DISTANCE_DEFAULT     110
+#define ZEBRA_ISIS_DISTANCE_DEFAULT      115
 #define ZEBRA_IBGP_DISTANCE_DEFAULT      200
 #define ZEBRA_EBGP_DISTANCE_DEFAULT       20