Isisd is now able to remove addresses from circuit and trigger LSP updates
if it's done. Some random fixes as well and update to sample configuration.
diff --git a/isisd/ChangeLog b/isisd/ChangeLog
index 3fa9f98..3dc341f 100644
--- a/isisd/ChangeLog
+++ b/isisd/ChangeLog
@@ -1,3 +1,18 @@
+2004-09-14 Hasso Tepper <hasso at quagga.net>
+
+	* isis_circuit.c: Mostly cosmetical changes in isis_circuit_add_addr()
+	  and add calls to isis_event_int_reach_change(). Implement
+	  isis_circuit_del_addr(). Cancel t_run_dr threads is circuit goes
+	  down.
+	* isis_events.c: Implement isis_event_int_reach_change(). I'm not sure
+	  yet how this stuff should work, but it allows be to start debug
+	  threads which act very weird at the moment.
+	* isis_tlv.c: Much less verbose by default.
+	* isis_zebra.c: Added extreme debugging output. Call connected_free()
+	  after isis_circuit_del_addr, not before.
+	* isisd.conf.sample: Update it a little bit. 10000 seconds hello time
+	  was certainly too much IMHO.
+
 2004-09-14 LIU Xin <lx at ns.6test.edu.cn>
 
 	* isis_pdu.c: Update l1_desig_is only if neighbor really is DIS.
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 9a41c58..eb83e98 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -216,64 +216,60 @@
 }
 
 void
-isis_circuit_add_addr (struct isis_circuit *circuit, struct connected *conn)
+isis_circuit_add_addr (struct isis_circuit *circuit,
+		       struct connected *connected)
 {
   struct prefix_ipv4 *ipv4;
   u_char buf[BUFSIZ];
 #ifdef HAVE_IPV6
   struct prefix_ipv6 *ipv6;
 #endif /* HAVE_IPV6 */
+
   if (!circuit->ip_addrs)
-    {
-      circuit->ip_addrs = list_new ();
-    }
+    circuit->ip_addrs = list_new ();
 #ifdef HAVE_IPV6
   if (!circuit->ipv6_link)
-    {
-      circuit->ipv6_link = list_new ();
-    }
+    circuit->ipv6_link = list_new ();
   if (!circuit->ipv6_non_link)
-    {
-      circuit->ipv6_non_link = list_new ();
-    }
+    circuit->ipv6_non_link = list_new ();
 #endif /* HAVE_IPV6 */
 
   memset (&buf, 0, BUFSIZ);
-  if (conn->address->family == AF_INET)
+  if (connected->address->family == AF_INET)
     {
       ipv4 = prefix_ipv4_new ();
-      ipv4->prefixlen = conn->address->prefixlen;
-      ipv4->prefix = conn->address->u.prefix4;
+      ipv4->prefixlen = connected->address->prefixlen;
+      ipv4->prefix = connected->address->u.prefix4;
       listnode_add (circuit->ip_addrs, ipv4);
-      prefix2str (conn->address, buf, BUFSIZ);
+      isis_event_int_reach_change (circuit);
+
 #ifdef EXTREME_DEBUG
+      prefix2str (connected->address, buf, BUFSIZ);
       zlog_info ("Added IP address %s to circuit %d", buf,
 		 circuit->circuit_id);
 #endif /* EXTREME_DEBUG */
     }
 #ifdef HAVE_IPV6
-  if (conn->address->family == AF_INET6)
+  if (connected->address->family == AF_INET6)
     {
       ipv6 = prefix_ipv6_new ();
-      ipv6->prefixlen = conn->address->prefixlen;
-      ipv6->prefix = conn->address->u.prefix6;
+      ipv6->prefixlen = connected->address->prefixlen;
+      ipv6->prefix = connected->address->u.prefix6;
+
       if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
-	{
-	  listnode_add (circuit->ipv6_link, ipv6);
-	}
+	listnode_add (circuit->ipv6_link, ipv6);
       else
-	{
-	  listnode_add (circuit->ipv6_non_link, ipv6);
-	}
-      prefix2str (conn->address, buf, BUFSIZ);
+	listnode_add (circuit->ipv6_non_link, ipv6);
+
+      isis_event_int_reach_change(circuit);
+
 #ifdef EXTREME_DEBUG
+      prefix2str (connected->address, buf, BUFSIZ);
       zlog_info ("Added IPv6 address %s to circuit %d", buf,
 		 circuit->circuit_id);
 #endif /* EXTREME_DEBUG */
     }
 #endif /* HAVE_IPV6 */
-
-
   return;
 }
 
@@ -281,7 +277,87 @@
 isis_circuit_del_addr (struct isis_circuit *circuit,
 		       struct connected *connected)
 {
+  struct prefix_ipv4 *ipv4, *ip = NULL;
+  struct listnode *node;
+  int found = 0;
+  u_char buf[BUFSIZ];
+#ifdef HAVE_IPV6
+  struct prefix_ipv6 *ipv6, *ip6 = NULL;
+#endif /* HAVE_IPV6 */
 
+  memset (&buf, 0, BUFSIZ);
+  if (connected->address->family == AF_INET)
+    {
+      ipv4 = prefix_ipv4_new ();
+      ipv4->prefixlen = connected->address->prefixlen;
+      ipv4->prefix = connected->address->u.prefix4;
+
+      for (node = listhead (circuit->ip_addrs); node; nextnode (node))
+	{
+	  ip = getdata (node);
+	  if (prefix_same ((struct prefix *) ip, (struct prefix *) &ipv4))
+	    break;
+	}
+
+      if (ip)
+	{
+	  listnode_delete (circuit->ip_addrs, ip);
+	  isis_event_int_reach_change (circuit);
+	}
+      else
+	{
+	  prefix2str (connected->address, buf, BUFSIZ);
+	  zlog_warn("Nonexitant ip address %s removal attempt from circuit \
+		     %d", buf, circuit->circuit_id);
+	}
+    }
+#ifdef HAVE_IPV6
+  if (connected->address->family == AF_INET6)
+    {
+      ipv6 = prefix_ipv6_new ();
+      ipv6->prefixlen = connected->address->prefixlen;
+      ipv6->prefix = connected->address->u.prefix6;
+
+      if (IN6_IS_ADDR_LINKLOCAL (&ipv6->prefix))
+	{
+	  for (node = listhead (circuit->ipv6_link); node; nextnode (node))
+	    {
+	      ip6 = getdata (node);
+	      if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
+		break;
+	    }
+	  if (ip6)
+	    {
+	      listnode_delete (circuit->ipv6_link, ip6);
+	      found = 1;
+	    }
+	}
+      else
+	{
+	  for (node = listhead (circuit->ipv6_non_link); node; nextnode (node))
+	    {
+	      ip6 = getdata (node);
+	      if (prefix_same ((struct prefix *) ip6, (struct prefix *) ipv6))
+		break;
+	    }
+	  if (ip6)
+	    {
+	      listnode_delete (circuit->ipv6_non_link, ip6);
+	      found = 1;
+	    }
+	}
+
+      if (!found)
+	{
+	  prefix2str (connected->address, buf, BUFSIZ);
+	  zlog_warn("Nonexitant ip address %s removal attempt from \
+		     circuit %d", buf, circuit->circuit_id);
+	}
+      else
+	isis_event_int_reach_change (circuit);
+    }
+#endif /* HAVE_IPV6 */
+  return;
 }
 
 void
@@ -516,6 +592,8 @@
     {
       THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[0]);
       THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[1]);
+      THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[0]);
+      THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[1]);
     }
   else if (circuit->circ_type == CIRCUIT_T_P2P)
     {
diff --git a/isisd/isis_events.c b/isisd/isis_events.c
index a99869b..16c6991 100644
--- a/isisd/isis_events.c
+++ b/isisd/isis_events.c
@@ -303,6 +303,20 @@
   return;
 }
 
+void
+isis_event_int_reach_change (struct isis_circuit *circuit)
+{
+  if (!circuit || !circuit->area)
+    return;
+
+  zlog_info ("ISIS-Evt (%s) Internal reachability change",
+	     circuit->area->area_tag);
+
+  lsp_regenerate_schedule (circuit->area);
+
+  return;
+}
+
 /* events supporting code */
 
 int
diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c
index a35b687..273d19c 100644
--- a/isisd/isis_tlv.c
+++ b/isisd/isis_tlv.c
@@ -437,8 +437,10 @@
 	      while (length > value_len)
 		{
 		  ipv4_addr = (struct in_addr *) pnt;
+#ifdef EXTREME_TLV_DEBUG
 		  zlog_info ("ISIS-TLV (%s) : IP ADDR %s, pnt %p", areatag,
 			     inet_ntoa (*ipv4_addr), pnt);
+#endif /* EXTREME_TLV_DEBUG */
 		  if (!tlvs->ipv4_addrs)
 		    tlvs->ipv4_addrs = list_new ();
 		  listnode_add (tlvs->ipv4_addrs, ipv4_addr);
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index ad5a050..e2f1dc5 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -199,6 +199,8 @@
 {
   struct connected *c;
   struct interface *ifp;
+  struct prefix *p;
+  u_char buf[BUFSIZ];
 
   c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
 				    zclient->ibuf);
@@ -208,9 +210,20 @@
 
   ifp = c->ifp;
 
-  connected_free (c);
+#ifdef EXTREME_DEBUG
+  p = c->address;
+  prefix2str (p, buf, BUFSIZ);
+
+  if (p->family == AF_INET)
+    zlog_info ("disconnected IP address %s", buf);
+#ifdef HAVE_IPV6
+  if (p->family == AF_INET6)
+    zlog_info ("disconnected IPv6 address %s", buf);
+#endif /* HAVE_IPV6 */
+#endif /* EXTREME_DEBUG */
 
   isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
+  connected_free (c);
 
   return 0;
 }
diff --git a/isisd/isisd.conf.sample b/isisd/isisd.conf.sample
index 9e08778..47b1595 100644
--- a/isisd/isisd.conf.sample
+++ b/isisd/isisd.conf.sample
@@ -2,14 +2,11 @@
 !
 ! ISISd sample configuration file
 !
-!
-!
 hostname isisd 
 password foo
 enable password foo
-!log stdout 
-log file /tmp/isisd.log
-! 
+log stdout 
+!log file /tmp/isisd.log
 ! 
 ! 
 router isis DEAD
@@ -21,10 +18,13 @@
 !  lsp-lifetime level-2 65535
 !  lsp-lifetime 65535
 
+!  hostname isisd-router
+!  area-password foobar
+!  domain-password foobar
+
 interface eth0
  ip router isis DEAD
- ip address 10.101.43.194
- isis hello-interval 10000 
+! isis hello-interval 5
 ! isis lsp-interval 1000
 
 ! -- optional
@@ -35,5 +35,5 @@
 ! isis retransmit-interval 10
 ! isis retransmit-throttle-interval
 ! isis hello-multiplier 2 level-1
-!
+! isis priority 64
 !