Esempio n. 1
0
/* Execute event process. */
int
bgp_event (struct thread *thread)
{
  int ret;
  int event;
  int next;
  struct peer *peer;

  peer = THREAD_ARG (thread);
  event = THREAD_VAL (thread);

  /* Logging this event. */
  next = FSM [peer->status -1][event - 1].next_state;

  if (BGP_DEBUG (fsm, FSM))
    plog_info (peer->log, "%s [FSM] %s (%s->%s)", peer->host, 
	       bgp_event_str[event],
	       LOOKUP (bgp_status_msg, peer->status),
	       LOOKUP (bgp_status_msg, next));
  if (BGP_DEBUG (normal, NORMAL)
      && strcmp (LOOKUP (bgp_status_msg, peer->status), LOOKUP (bgp_status_msg, next)))
    zlog_info ("%s went from %s to %s",
	       peer->host,
	       LOOKUP (bgp_status_msg, peer->status),
	       LOOKUP (bgp_status_msg, next));

  /* Call function. */
  ret = (*(FSM [peer->status - 1][event - 1].func))(peer);

  /* When function do not want proceed next job return -1. */
  if (ret < 0)
    return ret;
    
  /* If status is changed. */
  if (next != peer->status)
    bgp_fsm_change_status (peer, next);

  /* Make sure timer is set. */
  bgp_timer_set (peer);

  return 0;
}
Esempio n. 2
0
/* Execute event process. */
int
bgp_event (struct thread *thread)
{
  int ret = 0;
  int event;
  int next;
  struct peer *peer;

  peer = THREAD_ARG (thread);
  event = THREAD_VAL (thread);

  /* Logging this event. */
  next = FSM [peer->status -1][event - 1].next_state;

  if (BGP_DEBUG (fsm, FSM) && peer->status != next)
    plog_debug (peer->log, "%s [FSM] %s (%s->%s)", peer->host, 
	       bgp_event_str[event],
	       LOOKUP (bgp_status_msg, peer->status),
	       LOOKUP (bgp_status_msg, next));

  /* Call function. */
  if (FSM [peer->status -1][event - 1].func)
    ret = (*(FSM [peer->status - 1][event - 1].func))(peer);

  /* When function do not want proceed next job return -1. */
  if (ret >= 0)
    {
      /* If status is changed. */
      if (next != peer->status)
        bgp_fsm_change_status (peer, next);
      
      /* Make sure timer is set. */
      bgp_timer_set (peer);
    }
  
  return ret;
}
Esempio n. 3
0
/* Accept bgp connection. */
static int bgp_accept(struct thread *thread)
{
	int bgp_sock;
	int accept_sock;
	union sockunion su;
	struct bgp_listener *listener = THREAD_ARG(thread);
	struct peer *peer;
	struct peer *peer1;
	char buf[SU_ADDRSTRLEN];
	struct bgp *bgp = NULL;

	sockunion_init(&su);

	/* Register accept thread. */
	accept_sock = THREAD_FD(thread);
	if (accept_sock < 0) {
		flog_err_sys(EC_LIB_SOCKET, "accept_sock is nevative value %d",
			     accept_sock);
		return -1;
	}
	listener->thread = NULL;

	thread_add_read(bm->master, bgp_accept, listener, accept_sock,
			&listener->thread);

	/* Accept client connection. */
	bgp_sock = sockunion_accept(accept_sock, &su);
	if (bgp_sock < 0) {
		flog_err_sys(EC_LIB_SOCKET,
			     "[Error] BGP socket accept failed (%s)",
			     safe_strerror(errno));
		return -1;
	}
	set_nonblocking(bgp_sock);

	/* Obtain BGP instance this connection is meant for.
	 * - if it is a VRF netns sock, then BGP is in listener structure
	 * - otherwise, the bgp instance need to be demultiplexed
	 */
	if (listener->bgp)
		bgp = listener->bgp;
	else if (bgp_get_instance_for_inc_conn(bgp_sock, &bgp)) {
		if (bgp_debug_neighbor_events(NULL))
			zlog_debug(
				"[Event] Could not get instance for incoming conn from %s",
				inet_sutop(&su, buf));
		close(bgp_sock);
		return -1;
	}

	/* Set socket send buffer size */
	setsockopt_so_sendbuf(bgp_sock, BGP_SOCKET_SNDBUF_SIZE);

	/* Check remote IP address */
	peer1 = peer_lookup(bgp, &su);

	if (!peer1) {
		peer1 = peer_lookup_dynamic_neighbor(bgp, &su);
		if (peer1) {
			/* Dynamic neighbor has been created, let it proceed */
			peer1->fd = bgp_sock;
			bgp_fsm_change_status(peer1, Active);
			BGP_TIMER_OFF(
				peer1->t_start); /* created in peer_create() */

			if (peer_active(peer1))
				BGP_EVENT_ADD(peer1, TCP_connection_open);

			return 0;
		}
	}

	if (!peer1) {
		if (bgp_debug_neighbor_events(NULL)) {
			zlog_debug(
				"[Event] %s connection rejected - not configured"
				" and not valid for dynamic",
				inet_sutop(&su, buf));
		}
		close(bgp_sock);
		return -1;
	}

	if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN)) {
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"[Event] connection from %s rejected due to admin shutdown",
				inet_sutop(&su, buf));
		close(bgp_sock);
		return -1;
	}

	/*
	 * Do not accept incoming connections in Clearing state. This can result
	 * in incorect state transitions - e.g., the connection goes back to
	 * Established and then the Clearing_Completed event is generated. Also,
	 * block incoming connection in Deleted state.
	 */
	if (peer1->status == Clearing || peer1->status == Deleted) {
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"[Event] Closing incoming conn for %s (%p) state %d",
				peer1->host, peer1, peer1->status);
		close(bgp_sock);
		return -1;
	}

	/* Check that at least one AF is activated for the peer. */
	if (!peer_active(peer1)) {
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"%s - incoming conn rejected - no AF activated for peer",
				peer1->host);
		close(bgp_sock);
		return -1;
	}

	if (bgp_debug_neighbor_events(peer1))
		zlog_debug("[Event] BGP connection from host %s fd %d",
			   inet_sutop(&su, buf), bgp_sock);

	if (peer1->doppelganger) {
		/* We have an existing connection. Kill the existing one and run
		   with this one.
		*/
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"[Event] New active connection from peer %s, Killing"
				" previous active connection",
				peer1->host);
		peer_delete(peer1->doppelganger);
	}

	if (bgp_set_socket_ttl(peer1, bgp_sock) < 0)
		if (bgp_debug_neighbor_events(peer1))
			zlog_debug(
				"[Event] Unable to set min/max TTL on peer %s, Continuing",
				peer1->host);

	peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
			   peer1->as, peer1->as_type, 0, 0, NULL);
	hash_release(peer->bgp->peerhash, peer);
	hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);

	peer_xfer_config(peer, peer1);
	UNSET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);

	peer->doppelganger = peer1;
	peer1->doppelganger = peer;
	peer->fd = bgp_sock;
	vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer));
	bgp_fsm_change_status(peer, Active);
	BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */

	SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);

	/* Make dummy peer until read Open packet. */
	if (peer1->status == Established
	    && CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) {
		/* If we have an existing established connection with graceful
		 * restart
		 * capability announced with one or more address families, then
		 * drop
		 * existing established connection and move state to connect.
		 */
		peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
		SET_FLAG(peer1->sflags, PEER_STATUS_NSF_WAIT);
		bgp_event_update(peer1, TCP_connection_closed);
	}

	if (peer_active(peer)) {
		BGP_EVENT_ADD(peer, TCP_connection_open);
	}

	return 0;
}
Esempio n. 4
0
/* Status goes to Established.  Send keepalive packet then make first
   update information. */
static int
bgp_establish (struct peer *peer)
{
  struct bgp_notify *notify;
  afi_t afi;
  safi_t safi;
  int nsf_af_count = 0;

  /* Reset capability open status flag. */
  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
    SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);

  /* Clear last notification data. */
  notify = &peer->notify;
  if (notify->data)
    XFREE (MTYPE_TMP, notify->data);
  memset (notify, 0, sizeof (struct bgp_notify));

  /* Clear start timer value to default. */
  peer->v_start = BGP_INIT_START_TIMER;

  /* 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);

  /* graceful restart */
  UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
    for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
      {
	if (peer->afc_nego[afi][safi]
	    && CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)
	    && CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))
	  {
	    if (peer->nsf[afi][safi]
		&& ! CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV))
	      bgp_clear_stale_route (peer, afi, safi);

	    peer->nsf[afi][safi] = 1;
	    nsf_af_count++;
	  }
	else
	  {
	    if (peer->nsf[afi][safi])
	      bgp_clear_stale_route (peer, afi, safi);
	    peer->nsf[afi][safi] = 0;
	  }
      }

  if (nsf_af_count)
    SET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
  else
    {
      UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
      if (peer->t_gr_stale)
	{
	  BGP_TIMER_OFF (peer->t_gr_stale);
	  if (BGP_DEBUG (events, EVENTS))
	    zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
	}
    }

  if (peer->t_gr_restart)
    {
      BGP_TIMER_OFF (peer->t_gr_restart);
      if (BGP_DEBUG (events, EVENTS))
	zlog_debug ("%s graceful restart timer stopped", peer->host);
    }

#ifdef HAVE_SNMP
  bgpTrapEstablished (peer);
#endif /* HAVE_SNMP */

  /* Reset uptime, send keepalive, send current table. */
  peer->uptime = bgp_clock ();

  /* Send route-refresh when ORF is enabled */
  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
      if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV))
	{
	  if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
	    bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX,
				    REFRESH_IMMEDIATE, 0);
	  else if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))
	    bgp_route_refresh_send (peer, afi, safi, ORF_TYPE_PREFIX_OLD,
				    REFRESH_IMMEDIATE, 0);
	}

  if (peer->v_keepalive)
    bgp_keepalive_send (peer);

  /* First update is deferred until ORF or ROUTE-REFRESH is received */
  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
      if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV))
	if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
	    || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
	  SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);

  bgp_announce_route_all (peer);

  BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, 1);

  return 0;
}
Esempio n. 5
0
/* Administrative BGP peer stop event. */
int
bgp_stop (struct peer *peer)
{
  afi_t afi;
  safi_t safi;
  char orf_name[BUFSIZ];

  if (CHECK_FLAG (peer->sflags, PEER_STATUS_CREATE_INIT))
    return 0;

  /* Increment Dropped count. */
  if (peer->status == Established)
    {
      bgp_fsm_change_status (peer, Idle);
      peer->dropped++;

      /* bgp log-neighbor-changes of neighbor Down */
      if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
	zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host,
		   peer_down_str [(int) peer->last_reset]);

      /* graceful restart */
      if (peer->t_gr_stale)
	{
	  BGP_TIMER_OFF (peer->t_gr_stale);
	  if (BGP_DEBUG (events, EVENTS))
	    zlog_info ("%s graceful restart stalepath timer stopped", peer->host);
	}
      if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
	{
	  if (BGP_DEBUG (events, EVENTS))
	    {
	      zlog_info ("%s graceful restart timer started for %d sec",
			 peer->host, peer->v_gr_restart);
	      zlog_info ("%s graceful restart stalepath timer started for %d sec",
			 peer->host, peer->bgp->stalepath_time);
	    }
	  BGP_TIMER_ON (peer->t_gr_restart, bgp_graceful_restart_timer_expire,
			peer->v_gr_restart);
	  BGP_TIMER_ON (peer->t_gr_stale, bgp_graceful_stale_timer_expire,
			peer->bgp->stalepath_time);
	}
      else
	{
	  UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);

	  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
	    for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
	      peer->nsf[afi][safi] = 0;
	}

      /* set last reset time */
      peer->resettime = time (NULL);

#ifdef HAVE_SNMP
      bgpTrapBackwardTransition (peer);
#endif /* HAVE_SNMP */

      /* Reset uptime. */
      bgp_uptime_reset (peer);

      /* Need of clear of peer. */
      bgp_clear_route_all (peer);

      /* Reset peer synctime */
      for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
	for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
	  peer->synctime[afi][safi] = 0;
    }

  /* Stop read and write threads when exists. */
  BGP_READ_OFF (peer->t_read);
  BGP_WRITE_OFF (peer->t_write);

  /* Stop all timers. */
  BGP_TIMER_OFF (peer->t_start);
  BGP_TIMER_OFF (peer->t_connect);
  BGP_TIMER_OFF (peer->t_holdtime);
  BGP_TIMER_OFF (peer->t_keepalive);
  BGP_TIMER_OFF (peer->t_asorig);
  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
      BGP_TIMER_OFF (peer->t_routeadv[afi][safi]);

  /* Delete all existing events of the peer. */
  BGP_EVENT_DELETE (peer);

  /* Stream reset. */
  peer->packet_size = 0;

  /* Clear input and output buffer.  */
  if (peer->ibuf)
    stream_reset (peer->ibuf);
  if (peer->work)
    stream_reset (peer->work);
  stream_fifo_clean (peer->obuf);

  /* Close of file descriptor. */
  if (peer->fd >= 0)
    {
      close (peer->fd);
      peer->fd = -1;
    }

  /* Connection information. */
  if (peer->su_local)
    {
      XFREE (MTYPE_SOCKUNION, peer->su_local);
      peer->su_local = NULL;
    }

  if (peer->su_remote)
    {
      XFREE (MTYPE_SOCKUNION, peer->su_remote);
      peer->su_remote = NULL;
    }

  /* Clear remote router-id. */
  peer->remote_id.s_addr = 0;

  /* Clear peer capability flag. */
  peer->cap = 0;

  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
      {
	/* Reset all negotiated variables */
	peer->afc_nego[afi][safi] = 0;
	peer->afc_adv[afi][safi] = 0;
	peer->afc_recv[afi][safi] = 0;

	/* peer address family capability flags*/
	peer->af_cap[afi][safi] = 0;

	/* peer address family status flags*/
	peer->af_sflags[afi][safi] = 0;

	/* Received ORF prefix-filter */
	peer->orf_plist[afi][safi] = NULL;

        /* ORF received prefix-filter pnt */
        sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
        prefix_bgp_orf_remove_all (orf_name);
      }

  /* Reset keepalive and holdtime */
  if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
    {
      peer->v_keepalive = peer->keepalive;
      peer->v_holdtime = peer->holdtime;
    }
  else
    {
      peer->v_keepalive = peer->bgp->default_keepalive;
      peer->v_holdtime = peer->bgp->default_holdtime;
    }

  peer->update_time = 0;

  /* Until we are sure that there is no problem about prefix count
     this should be commented out.*/
#if 0
  /* Reset prefix count */
  peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
  peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
  peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
  peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
  peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
#endif /* 0 */

  return 0;
}
Esempio n. 6
0
/* Administrative BGP peer stop event. */
int
bgp_stop (struct peer *peer)
{
  int established = 0;
  afi_t afi;
  safi_t safi;
  char orf_name[BUFSIZ];

  /* Increment Dropped count. */
  if (peer->status == Established)
    {
      established = 1;
      peer->dropped++;
      bgp_fsm_change_status (peer, Idle);
#ifdef HAVE_SNMP
      bgpTrapBackwardTransition (peer);
#endif /* HAVE_SNMP */
    }

  /* Reset uptime. */
  bgp_uptime_reset (peer);

  /* Need of clear of peer. */
  if (established)
    bgp_clear_route_all (peer);

  /* Stop read and write threads when exists. */
  BGP_READ_OFF (peer->t_read);
  BGP_WRITE_OFF (peer->t_write);

  /* Stop all timers. */
  BGP_TIMER_OFF (peer->t_start);
  BGP_TIMER_OFF (peer->t_connect);
  BGP_TIMER_OFF (peer->t_holdtime);
  BGP_TIMER_OFF (peer->t_keepalive);
  BGP_TIMER_OFF (peer->t_asorig);
  BGP_TIMER_OFF (peer->t_routeadv);

  /* Delete all existing events of the peer. */
  BGP_EVENT_DELETE (peer);

  /* Stream reset. */
  peer->packet_size = 0;

  /* Clear input and output buffer.  */
  if (peer->ibuf)
    stream_reset (peer->ibuf);
  if (peer->work)
    stream_reset (peer->work);
  stream_fifo_clean (peer->obuf);

  /* Close of file descriptor. */
  if (peer->fd >= 0)
    {
      close (peer->fd);
      peer->fd = -1;
    }

  /* Connection information. */
  if (peer->su_local)
    {
      XFREE (MTYPE_SOCKUNION, peer->su_local);
      peer->su_local = NULL;
    }

  if (peer->su_remote)
    {
      XFREE (MTYPE_SOCKUNION, peer->su_remote);
      peer->su_remote = NULL;
    }

  /* Clear remote router-id. */
  peer->remote_id.s_addr = 0;

  /* Reset all negotiated variables */
  peer->afc_nego[AFI_IP][SAFI_UNICAST] = 0;
  peer->afc_nego[AFI_IP][SAFI_MULTICAST] = 0;
  peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] = 0;
  peer->afc_nego[AFI_IP6][SAFI_UNICAST] = 0;
  peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = 0;
  peer->afc_adv[AFI_IP][SAFI_UNICAST] = 0;
  peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 0;
  peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 0;
  peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 0;
  peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 0;
  peer->afc_recv[AFI_IP][SAFI_UNICAST] = 0;
  peer->afc_recv[AFI_IP][SAFI_MULTICAST] = 0;
  peer->afc_recv[AFI_IP][SAFI_MPLS_VPN] = 0;
  peer->afc_recv[AFI_IP6][SAFI_UNICAST] = 0;
  peer->afc_recv[AFI_IP6][SAFI_MULTICAST] = 0;

  /* Reset route refresh flag. */
  UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
  UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
  UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
  UNSET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
  UNSET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);

  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
      {
	/* peer address family capability flags*/
	peer->af_cap[afi][safi] = 0;
	/* peer address family status flags*/
	peer->af_sflags[afi][safi] = 0;
	/* Received ORF prefix-filter */
	peer->orf_plist[afi][safi] = NULL;
        /* ORF received prefix-filter pnt */
        sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
        prefix_bgp_orf_remove_all (orf_name);
      }

  UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
	      PEER_FLAG_DEFAULT_ORIGINATE_CHECK);
  UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
	      PEER_FLAG_DEFAULT_ORIGINATE_CHECK);
  UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
	      PEER_FLAG_DEFAULT_ORIGINATE_CHECK);
  UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],
	      PEER_FLAG_DEFAULT_ORIGINATE_CHECK);

  /* Reset keepalive and holdtime */
  if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
    {
      peer->v_keepalive = peer->keepalive;
      peer->v_holdtime = peer->holdtime;
    }
  else
    {
      peer->v_keepalive = peer->bgp->default_keepalive;
      peer->v_holdtime = peer->bgp->default_holdtime;
    }

  peer->update_time = 0;

  /* Until we are sure that there is no problem about prefix count
     this should be commented out.*/
#if 0
  /* Reset prefix count */
  peer->pcount[AFI_IP][SAFI_UNICAST] = 0;
  peer->pcount[AFI_IP][SAFI_MULTICAST] = 0;
  peer->pcount[AFI_IP][SAFI_MPLS_VPN] = 0;
  peer->pcount[AFI_IP6][SAFI_UNICAST] = 0;
  peer->pcount[AFI_IP6][SAFI_MULTICAST] = 0;
#endif /* 0 */

  return 0;
}