2003-08-13 kunihiro <kunihiro@zebra.org>

	* bgpd/bgp{_fsm.c,_vty.c,d.c,d.h}: Add support for "bgp
          log-neighbor-changes" command.
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 64a4c1b..3d8e957 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -322,6 +322,14 @@
       established = 1;
       peer->dropped++;
       bgp_fsm_change_status (peer, Idle);
+
+      /* bgp log-neighbor-changes of neighbor Down */
+      if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
+	zlog_info ("%%ADJCHANGE: neighbor %s Down", peer->host);
+
+      /* set last reset time */
+      peer->resettime = time (NULL);
+
 #ifdef HAVE_SNMP
       bgpTrapBackwardTransition (peer);
 #endif /* HAVE_SNMP */
@@ -629,6 +637,11 @@
   /* Increment established count. */
   peer->established++;
   bgp_fsm_change_status (peer, Established);
+
+  /* bgp log-neighbor-changes of neighbor Up */
+  if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
+    zlog_info ("%%ADJCHANGE: neighbor %s Up", peer->host);
+
 #ifdef HAVE_SNMP
   bgpTrapEstablished (peer);
 #endif /* HAVE_SNMP */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 6514ac2..39a43c0 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -878,6 +878,34 @@
   return CMD_SUCCESS;
 }
 
+/* "bgp log-neighbor-changes" configuration.  */
+DEFUN (bgp_log_neighbor_changes,
+       bgp_log_neighbor_changes_cmd,
+       "bgp log-neighbor-changes",
+       "BGP specific commands\n"
+       "Log neighbor up/down and reset reason\n")
+{
+  struct bgp *bgp;
+
+  bgp = vty->index;
+  bgp_flag_set (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_log_neighbor_changes,
+       no_bgp_log_neighbor_changes_cmd,
+       "no bgp log-neighbor-changes",
+       NO_STR
+       "BGP specific commands\n"
+       "Log neighbor up/down and reset reason\n")
+{
+  struct bgp *bgp;
+
+  bgp = vty->index;
+  bgp_flag_unset (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+  return CMD_SUCCESS;
+}
+
 /* "bgp bestpath med" configuration. */
 DEFUN (bgp_bestpath_med,
        bgp_bestpath_med_cmd,
@@ -6660,6 +6688,9 @@
 	   p->established, p->dropped,
 	   VTY_NEWLINE);
 
+  vty_out (vty, "  Last reset %s%s", p->dropped ? peer_uptime (p->resettime, timebuf, BGP_UPTIME_LEN) : "never",
+	   VTY_NEWLINE);
+
   if (CHECK_FLAG (p->sflags, PEER_STATUS_PREFIX_OVERFLOW))
     {
       vty_out (vty, "  Peer had exceeded the max. no. of prefixes configured.%s", VTY_NEWLINE);
@@ -7743,6 +7774,10 @@
   install_element (BGP_NODE, &bgp_bestpath_aspath_ignore_cmd);
   install_element (BGP_NODE, &no_bgp_bestpath_aspath_ignore_cmd);
 
+  /* "bgp log-neighbor-changes" commands */
+  install_element (BGP_NODE, &bgp_log_neighbor_changes_cmd);
+  install_element (BGP_NODE, &no_bgp_log_neighbor_changes_cmd);
+
   /* "bgp bestpath med" commands */
   install_element (BGP_NODE, &bgp_bestpath_med_cmd);
   install_element (BGP_NODE, &bgp_bestpath_med2_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index f116a0c..3a12a27 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -752,6 +752,9 @@
   /* Last read time set */
   peer->readtime = time (NULL);
 
+  /* Last reset time set */
+  peer->resettime = time (NULL);
+
   /* Default TTL set. */
   peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
 
@@ -797,6 +800,13 @@
   type = peer_sort (peer);
   peer->as = as;
 
+  if (bgp_config_check (peer->bgp, BGP_CONFIG_CONFEDERATION)
+      && ! bgp_confederation_peers_check (peer->bgp, as)
+      && peer->bgp->as != as)
+    peer->local_as = peer->bgp->confed_id;
+  else
+    peer->local_as = peer->bgp->as;
+
   /* Advertisement-interval reset */
   if (peer_sort (peer) == BGP_PEER_IBGP)
     peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
@@ -1634,6 +1644,15 @@
   return bgp;
 }
 
+/* Return master of BGP. */
+struct bgp_master *
+bgp_get_master ()
+{
+  if (bm)
+    return bm;
+  return NULL;
+}
+
 /* Return first entry of BGP. */
 struct bgp *
 bgp_get_default ()
@@ -4415,6 +4434,10 @@
 	vty_out (vty, " bgp router-id %s%s", inet_ntoa (bgp->router_id), 
 		 VTY_NEWLINE);
 
+      /* BGP log-neighbor-changes. */
+      if (bgp_flag_check (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
+	vty_out (vty, " bgp log-neighbor-changes%s", VTY_NEWLINE);
+
       /* BGP configuration. */
       if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
 	vty_out (vty, " bgp always-compare-med%s", VTY_NEWLINE);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 11c6bde..498bd07 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -96,6 +96,7 @@
 #define BGP_FLAG_ASPATH_IGNORE            (1 << 8)
 #define BGP_FLAG_IMPORT_CHECK             (1 << 9)
 #define BGP_FLAG_NO_FAST_EXT_FAILOVER     (1 << 10)
+#define BGP_FLAG_LOG_NEIGHBOR_CHANGES     (1 << 11)
 
   /* BGP Per AF flags */
   u_int16_t af_flags[AFI_MAX][SAFI_MAX];
@@ -263,6 +264,7 @@
   union sockunion su;		/* Sockunion address of the peer. */
   time_t uptime;		/* Last Up/Down time */
   time_t readtime;		/* Last read time */
+  time_t resettime;		/* Last reset time */
   
   unsigned int ifindex;		/* ifindex of the BGP connection. */
   char *ifname;			/* bind interface name. */