Diff for /embedaddon/quagga/bgpd/bgpd.c between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2013/07/21 23:54:38 version 1.1.1.4, 2016/11/02 10:09:10
Line 26  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 26  Software Foundation, Inc., 59 Temple Place - Suite 330
 #include "stream.h"  #include "stream.h"
 #include "command.h"  #include "command.h"
 #include "sockunion.h"  #include "sockunion.h"
   #include "sockopt.h"
 #include "network.h"  #include "network.h"
 #include "memory.h"  #include "memory.h"
 #include "filter.h"  #include "filter.h"
Line 35  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 36  Software Foundation, Inc., 59 Temple Place - Suite 330
 #include "plist.h"  #include "plist.h"
 #include "linklist.h"  #include "linklist.h"
 #include "workqueue.h"  #include "workqueue.h"
   #include "table.h"
   
 #include "bgpd/bgpd.h"  #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"  #include "bgpd/bgp_table.h"
Line 54  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 56  Software Foundation, Inc., 59 Temple Place - Suite 330
 #include "bgpd/bgp_nexthop.h"  #include "bgpd/bgp_nexthop.h"
 #include "bgpd/bgp_damp.h"  #include "bgpd/bgp_damp.h"
 #include "bgpd/bgp_mplsvpn.h"  #include "bgpd/bgp_mplsvpn.h"
   #include "bgpd/bgp_encap.h"
 #include "bgpd/bgp_advertise.h"  #include "bgpd/bgp_advertise.h"
 #include "bgpd/bgp_network.h"  #include "bgpd/bgp_network.h"
 #include "bgpd/bgp_vty.h"  #include "bgpd/bgp_vty.h"
Line 61  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 64  Software Foundation, Inc., 59 Temple Place - Suite 330
 #ifdef HAVE_SNMP  #ifdef HAVE_SNMP
 #include "bgpd/bgp_snmp.h"  #include "bgpd/bgp_snmp.h"
 #endif /* HAVE_SNMP */  #endif /* HAVE_SNMP */
 /* BGP process wide configuration.  */  /* BGP process wide configuration.  */
 static struct bgp_master bgp_master;  static struct bgp_master bgp_master;
   
Line 72  struct bgp_master *bm; Line 75  struct bgp_master *bm;
   
 /* BGP community-list.  */  /* BGP community-list.  */
 struct community_list_handler *bgp_clist;  struct community_list_handler *bgp_clist;
 /* BGP global flag manipulation.  */  /* BGP global flag manipulation.  */
 int  int
 bgp_option_set (int flag)  bgp_option_set (int flag)
Line 115  bgp_option_check (int flag) Line 118  bgp_option_check (int flag)
 {  {
   return CHECK_FLAG (bm->options, flag);    return CHECK_FLAG (bm->options, flag);
 }  }
 /* BGP flag manipulation.  */  /* BGP flag manipulation.  */
 int  int
 bgp_flag_set (struct bgp *bgp, int flag)  bgp_flag_set (struct bgp *bgp, int flag)
Line 136  bgp_flag_check (struct bgp *bgp, int flag) Line 139  bgp_flag_check (struct bgp *bgp, int flag)
 {  {
   return CHECK_FLAG (bgp->flags, flag);    return CHECK_FLAG (bgp->flags, flag);
 }  }
 /* Internal function to set BGP structure configureation flag.  */  /* Internal function to set BGP structure configureation flag.  */
 static void  static void
 bgp_config_set (struct bgp *bgp, int config)  bgp_config_set (struct bgp *bgp, int config)
Line 155  bgp_config_check (struct bgp *bgp, int config) Line 158  bgp_config_check (struct bgp *bgp, int config)
 {  {
   return CHECK_FLAG (bgp->config, config);    return CHECK_FLAG (bgp->config, config);
 }  }
 /* Set BGP router identifier. */  /* Set BGP router identifier. */
 int  int
 bgp_router_id_set (struct bgp *bgp, struct in_addr *id)  bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
Line 175  bgp_router_id_set (struct bgp *bgp, struct in_addr *id Line 178  bgp_router_id_set (struct bgp *bgp, struct in_addr *id
     {      {
       IPV4_ADDR_COPY (&peer->local_id, id);        IPV4_ADDR_COPY (&peer->local_id, id);
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_RID_CHANGE;           peer->last_reset = PEER_DOWN_RID_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 205  bgp_cluster_id_set (struct bgp *bgp, struct in_addr *c Line 208  bgp_cluster_id_set (struct bgp *bgp, struct in_addr *c
       if (peer->sort != BGP_PEER_IBGP)        if (peer->sort != BGP_PEER_IBGP)
         continue;          continue;
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_CLID_CHANGE;           peer->last_reset = PEER_DOWN_CLID_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 233  bgp_cluster_id_unset (struct bgp *bgp) Line 236  bgp_cluster_id_unset (struct bgp *bgp)
       if (peer->sort != BGP_PEER_IBGP)        if (peer->sort != BGP_PEER_IBGP)
         continue;          continue;
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_CLID_CHANGE;           peer->last_reset = PEER_DOWN_CLID_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 242  bgp_cluster_id_unset (struct bgp *bgp) Line 245  bgp_cluster_id_unset (struct bgp *bgp)
     }      }
   return 0;    return 0;
 }  }
 /* time_t value that is monotonicly increasing  /* time_t value that is monotonicly increasing
  * and uneffected by adjustments to system clock   * and uneffected by adjustments to system clock
  */   */
Line 273  bgp_timers_unset (struct bgp *bgp) Line 276  bgp_timers_unset (struct bgp *bgp)
   
   return 0;    return 0;
 }  }
 /* BGP confederation configuration.  */  /* BGP confederation configuration.  */
 int  int
 bgp_confederation_id_set (struct bgp *bgp, as_t as)  bgp_confederation_id_set (struct bgp *bgp, as_t as)
Line 302  bgp_confederation_id_set (struct bgp *bgp, as_t as) Line 305  bgp_confederation_id_set (struct bgp *bgp, as_t as)
           if (peer_sort (peer) == BGP_PEER_EBGP)            if (peer_sort (peer) == BGP_PEER_EBGP)
             {              {
               peer->local_as = as;                peer->local_as = as;
              if (peer->status == Established)              if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
                {                 {
                  peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;                   peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,                   bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 322  bgp_confederation_id_set (struct bgp *bgp, as_t as) Line 325  bgp_confederation_id_set (struct bgp *bgp, as_t as)
               /* Reset the local_as to be our EBGP one */                /* Reset the local_as to be our EBGP one */
               if (peer_sort (peer) == BGP_PEER_EBGP)                if (peer_sort (peer) == BGP_PEER_EBGP)
                 peer->local_as = as;                  peer->local_as = as;
              if (peer->status == Established)              if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
                {                 {
                  peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;                   peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,                   bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 351  bgp_confederation_id_unset (struct bgp *bgp) Line 354  bgp_confederation_id_unset (struct bgp *bgp)
       if (peer_sort (peer) != BGP_PEER_IBGP)        if (peer_sort (peer) != BGP_PEER_IBGP)
         {          {
           peer->local_as = bgp->as;            peer->local_as = bgp->as;
          if (peer->status == Established)          if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
            {             {
              peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;               peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
              bgp_notify_send (peer, BGP_NOTIFY_CEASE,               bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 415  bgp_confederation_peers_add (struct bgp *bgp, as_t as) Line 418  bgp_confederation_peers_add (struct bgp *bgp, as_t as)
           if (peer->as == as)            if (peer->as == as)
             {              {
               peer->local_as = bgp->as;                peer->local_as = bgp->as;
              if (peer->status == Established)              if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
                {                 {
                  peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;                   peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,                   bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 471  bgp_confederation_peers_remove (struct bgp *bgp, as_t  Line 474  bgp_confederation_peers_remove (struct bgp *bgp, as_t 
           if (peer->as == as)            if (peer->as == as)
             {              {
               peer->local_as = bgp->confed_id;                peer->local_as = bgp->confed_id;
              if (peer->status == Established)              if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
                {                 {
                  peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;                   peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,                   bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 485  bgp_confederation_peers_remove (struct bgp *bgp, as_t  Line 488  bgp_confederation_peers_remove (struct bgp *bgp, as_t 
   
   return 0;    return 0;
 }  }
 /* Local preference configuration.  */  /* Local preference configuration.  */
 int  int
 bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref)  bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref)
Line 508  bgp_default_local_preference_unset (struct bgp *bgp) Line 511  bgp_default_local_preference_unset (struct bgp *bgp)
   
   return 0;    return 0;
 }  }
 /* If peer is RSERVER_CLIENT in at least one address family and is not member  /* If peer is RSERVER_CLIENT in at least one address family and is not member
     of a peer_group for that family, return 1.      of a peer_group for that family, return 1.
     Used to check wether the peer is included in list bgp->rsclient. */      Used to check wether the peer is included in list bgp->rsclient. */
Line 595  peer_af_flag_reset (struct peer *peer, afi_t afi, safi Line 598  peer_af_flag_reset (struct peer *peer, afi_t afi, safi
   /* Clear ORF info */    /* Clear ORF info */
   peer->orf_plist[afi][safi] = NULL;    peer->orf_plist[afi][safi] = NULL;
   sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);    sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
  prefix_bgp_orf_remove_all (orf_name);  prefix_bgp_orf_remove_all (afi, orf_name);
   
   /* Set default neighbor send-community.  */    /* Set default neighbor send-community.  */
   if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))    if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
Line 721  peer_free (struct peer *peer) Line 724  peer_free (struct peer *peer)
   BGP_EVENT_FLUSH (peer);    BGP_EVENT_FLUSH (peer);
       
   if (peer->desc)    if (peer->desc)
    XFREE (MTYPE_PEER_DESC, peer->desc);    {
       XFREE (MTYPE_PEER_DESC, peer->desc);
       peer->desc = NULL;
     }
       
   /* Free allocated host character. */    /* Free allocated host character. */
   if (peer->host)    if (peer->host)
    XFREE (MTYPE_BGP_PEER_HOST, peer->host);    {
        XFREE (MTYPE_BGP_PEER_HOST, peer->host);
       peer->host = NULL;
     }
 
   /* Update source configuration.  */    /* Update source configuration.  */
   if (peer->update_source)    if (peer->update_source)
    sockunion_free (peer->update_source);    {
       sockunion_free (peer->update_source);
       peer->update_source = NULL;
     }
       
   if (peer->update_if)    if (peer->update_if)
    XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);    {
       XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
       peer->update_if = NULL;
     }
           
   if (peer->clear_node_queue)    if (peer->clear_node_queue)
    work_queue_free (peer->clear_node_queue);    {
       work_queue_free(peer->clear_node_queue);
       peer->clear_node_queue = NULL;
     }
       
     if (peer->notify.data)
       XFREE(MTYPE_TMP, peer->notify.data);
     
   bgp_sync_delete (peer);    bgp_sync_delete (peer);
   memset (peer, 0, sizeof (struct peer));    memset (peer, 0, sizeof (struct peer));
       
Line 745  peer_free (struct peer *peer) Line 766  peer_free (struct peer *peer)
                                                                                                   
 /* increase reference count on a struct peer */  /* increase reference count on a struct peer */
 struct peer *  struct peer *
peer_lock (struct peer *peer)peer_lock_with_caller (const char *name, struct peer *peer)
 {  {
   assert (peer && (peer->lock >= 0));    assert (peer && (peer->lock >= 0));
    
 #if 0
   zlog_debug("%s peer_lock %p %d", name, peer, peer->lock);
 #endif
 
   peer->lock++;    peer->lock++;
       
   return peer;    return peer;
Line 758  peer_lock (struct peer *peer) Line 783  peer_lock (struct peer *peer)
  * struct peer is freed and NULL returned if last reference   * struct peer is freed and NULL returned if last reference
  */   */
 struct peer *  struct peer *
peer_unlock (struct peer *peer)peer_unlock_with_caller (const char *name, struct peer *peer)
 {  {
   assert (peer && (peer->lock > 0));    assert (peer && (peer->lock > 0));
  
 #if 0
   zlog_debug("%s peer_unlock %p %d", name, peer, peer->lock);
 #endif
 
   peer->lock--;    peer->lock--;
       
   if (peer->lock == 0)    if (peer->lock == 0)
     {      {
 #if 0  
       zlog_debug ("unlocked and freeing");  
       zlog_backtrace (LOG_DEBUG);  
 #endif  
       peer_free (peer);        peer_free (peer);
       return NULL;        return NULL;
     }      }
   
 #if 0  
   if (peer->lock == 1)  
     {  
       zlog_debug ("unlocked to 1");  
       zlog_backtrace (LOG_DEBUG);  
     }  
 #endif  
   
   return peer;    return peer;
 }  }
       
Line 806  peer_new (struct bgp *bgp) Line 823  peer_new (struct bgp *bgp)
   peer->fd = -1;    peer->fd = -1;
   peer->v_start = BGP_INIT_START_TIMER;    peer->v_start = BGP_INIT_START_TIMER;
   peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;    peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
   peer->v_asorig = BGP_DEFAULT_ASORIGINATE;  
   peer->status = Idle;    peer->status = Idle;
   peer->ostatus = Idle;    peer->ostatus = Idle;
   peer->weight = 0;    peer->weight = 0;
Line 832  peer_new (struct bgp *bgp) Line 848  peer_new (struct bgp *bgp)
   peer->ibuf = stream_new (BGP_MAX_PACKET_SIZE);    peer->ibuf = stream_new (BGP_MAX_PACKET_SIZE);
   peer->obuf = stream_fifo_new ();    peer->obuf = stream_fifo_new ();
   peer->work = stream_new (BGP_MAX_PACKET_SIZE);    peer->work = stream_new (BGP_MAX_PACKET_SIZE);
     peer->scratch = stream_new (BGP_MAX_PACKET_SIZE);
   
   bgp_sync_init (peer);    bgp_sync_init (peer);
   
Line 907  static void Line 924  static void
 peer_as_change (struct peer *peer, as_t as)  peer_as_change (struct peer *peer, as_t as)
 {  {
   bgp_peer_sort_t type;    bgp_peer_sort_t type;
     struct peer *conf;
   
   /* Stop peer. */    /* Stop peer. */
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {      {
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;           peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 931  peer_as_change (struct peer *peer, as_t as) Line 949  peer_as_change (struct peer *peer, as_t as)
     peer->local_as = peer->bgp->as;      peer->local_as = peer->bgp->as;
   
   /* Advertisement-interval reset */    /* Advertisement-interval reset */
  if (peer_sort (peer) == BGP_PEER_IBGP)  conf = NULL;
    peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;  if (peer->group)
     conf = peer->group->conf;
 
   if (conf && CHECK_FLAG (conf->config, PEER_CONFIG_ROUTEADV))
       peer->v_routeadv = conf->routeadv;
   else    else
    peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;    if (peer_sort (peer) == BGP_PEER_IBGP)
       peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
     else
       peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
   
   /* TTL reset */    /* TTL reset */
   if (peer_sort (peer) == BGP_PEER_IBGP)    if (peer_sort (peer) == BGP_PEER_IBGP)
Line 951  peer_as_change (struct peer *peer, as_t as) Line 976  peer_as_change (struct peer *peer, as_t as)
                   PEER_FLAG_REFLECTOR_CLIENT);                    PEER_FLAG_REFLECTOR_CLIENT);
       UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN],        UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN],
                   PEER_FLAG_REFLECTOR_CLIENT);                    PEER_FLAG_REFLECTOR_CLIENT);
         UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_ENCAP],
                     PEER_FLAG_REFLECTOR_CLIENT);
       UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],        UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
                   PEER_FLAG_REFLECTOR_CLIENT);                    PEER_FLAG_REFLECTOR_CLIENT);
       UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],        UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],
                   PEER_FLAG_REFLECTOR_CLIENT);                    PEER_FLAG_REFLECTOR_CLIENT);
         UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MPLS_VPN],
                     PEER_FLAG_REFLECTOR_CLIENT);
         UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_ENCAP],
                     PEER_FLAG_REFLECTOR_CLIENT);
     }      }
   
   /* local-as reset */    /* local-as reset */
Line 1027  peer_remote_as (struct bgp *bgp, union sockunion *su,  Line 1058  peer_remote_as (struct bgp *bgp, union sockunion *su, 
   
       if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)        if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
           && afi == AFI_IP && safi == SAFI_UNICAST)            && afi == AFI_IP && safi == SAFI_UNICAST)
        peer = peer_create (su, bgp, local_as, *as, 0, 0);         peer_create (su, bgp, local_as, *as, 0, 0); 
       else        else
        peer = peer_create (su, bgp, local_as, *as, afi, safi);         peer_create (su, bgp, local_as, *as, afi, safi); 
     }      }
   
   return 0;    return 0;
Line 1267  peer_delete (struct peer *peer) Line 1298  peer_delete (struct peer *peer)
   
   /* Buffers.  */    /* Buffers.  */
   if (peer->ibuf)    if (peer->ibuf)
    stream_free (peer->ibuf);    {
       stream_free (peer->ibuf);
       peer->ibuf = NULL;
     }
 
   if (peer->obuf)    if (peer->obuf)
    stream_fifo_free (peer->obuf);    {
       stream_fifo_free (peer->obuf);
       peer->obuf = NULL;
     }
 
   if (peer->work)    if (peer->work)
    stream_free (peer->work);    {
  peer->obuf = NULL;      stream_free (peer->work);
  peer->work = peer->ibuf = NULL;      peer->work = NULL;
     }
   
     if (peer->scratch)
       {
         stream_free(peer->scratch);
         peer->scratch = NULL;
       }
   
   /* Local and remote addresses. */    /* Local and remote addresses. */
   if (peer->su_local)    if (peer->su_local)
    sockunion_free (peer->su_local);    {
       sockunion_free (peer->su_local);
       peer->su_local = NULL;
     }
 
   if (peer->su_remote)    if (peer->su_remote)
    sockunion_free (peer->su_remote);    {
  peer->su_local = peer->su_remote = NULL;      sockunion_free (peer->su_remote);
       peer->su_remote = NULL;
     }
       
   /* Free filter related memory.  */    /* Free filter related memory.  */
   for (afi = AFI_IP; afi < AFI_MAX; afi++)    for (afi = AFI_IP; afi < AFI_MAX; afi++)
Line 1291  peer_delete (struct peer *peer) Line 1343  peer_delete (struct peer *peer)
         for (i = FILTER_IN; i < FILTER_MAX; i++)          for (i = FILTER_IN; i < FILTER_MAX; i++)
           {            {
             if (filter->dlist[i].name)              if (filter->dlist[i].name)
              free (filter->dlist[i].name);              {
                 free(filter->dlist[i].name);
                 filter->dlist[i].name = NULL;
               }
 
             if (filter->plist[i].name)              if (filter->plist[i].name)
              free (filter->plist[i].name);              {
                 free(filter->plist[i].name);
                 filter->plist[i].name = NULL;
               }
 
             if (filter->aslist[i].name)              if (filter->aslist[i].name)
              free (filter->aslist[i].name);              {
                            free(filter->aslist[i].name);
            filter->dlist[i].name = NULL;                filter->aslist[i].name = NULL;
            filter->plist[i].name = NULL;              }
            filter->aslist[i].name = NULL; 
           }            }
   
         for (i = RMAP_IN; i < RMAP_MAX; i++)          for (i = RMAP_IN; i < RMAP_MAX; i++)
           {            {
             if (filter->map[i].name)              if (filter->map[i].name)
              free (filter->map[i].name);              {
            filter->map[i].name = NULL;                free (filter->map[i].name);
                 filter->map[i].name = NULL;
               }
           }            }
   
         if (filter->usmap.name)          if (filter->usmap.name)
          free (filter->usmap.name);          {
             free (filter->usmap.name);
             filter->usmap.name = NULL;
           }
   
         if (peer->default_rmap[afi][safi].name)          if (peer->default_rmap[afi][safi].name)
          free (peer->default_rmap[afi][safi].name);          {
                    free (peer->default_rmap[afi][safi].name);
        filter->usmap.name = NULL;            peer->default_rmap[afi][safi].name = NULL;
        peer->default_rmap[afi][safi].name = NULL;          }
       }        }
       
     if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETING))
       bgp_peer_clear_node_queue_drain_immediate(peer);
   
   peer_unlock (peer); /* initial reference */    peer_unlock (peer); /* initial reference */
   
   return 0;    return 0;
 }  }
 static int  static int
 peer_group_cmp (struct peer_group *g1, struct peer_group *g2)  peer_group_cmp (struct peer_group *g1, struct peer_group *g2)
 {  {
Line 1336  peer_group_active (struct peer *peer) Line 1404  peer_group_active (struct peer *peer)
   if (peer->af_group[AFI_IP][SAFI_UNICAST]    if (peer->af_group[AFI_IP][SAFI_UNICAST]
       || peer->af_group[AFI_IP][SAFI_MULTICAST]        || peer->af_group[AFI_IP][SAFI_MULTICAST]
       || peer->af_group[AFI_IP][SAFI_MPLS_VPN]        || peer->af_group[AFI_IP][SAFI_MPLS_VPN]
         || peer->af_group[AFI_IP][SAFI_ENCAP]
       || peer->af_group[AFI_IP6][SAFI_UNICAST]        || peer->af_group[AFI_IP6][SAFI_UNICAST]
      || peer->af_group[AFI_IP6][SAFI_MULTICAST])      || peer->af_group[AFI_IP6][SAFI_MULTICAST]
       || peer->af_group[AFI_IP6][SAFI_MPLS_VPN]
       || peer->af_group[AFI_IP6][SAFI_ENCAP])
     return 1;      return 1;
   return 0;    return 0;
 }  }
Line 1451  peer_group2peer_config_copy (struct peer_group *group, Line 1522  peer_group2peer_config_copy (struct peer_group *group,
     peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;      peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
   
   /* advertisement-interval reset */    /* advertisement-interval reset */
  if (peer_sort (peer) == BGP_PEER_IBGP)  if (CHECK_FLAG (conf->config, PEER_CONFIG_ROUTEADV))
    peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;      peer->v_routeadv = conf->routeadv;
   else    else
    peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;      if (peer_sort (peer) == BGP_PEER_IBGP)
         peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
       else
         peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
   
   /* password apply */    /* password apply */
  if (peer->password)  if (conf->password && !peer->password)
    XFREE (MTYPE_PEER_PASSWORD, peer->password); 
 
  if (conf->password) 
     peer->password =  XSTRDUP (MTYPE_PEER_PASSWORD, conf->password);      peer->password =  XSTRDUP (MTYPE_PEER_PASSWORD, conf->password);
   else  
     peer->password = NULL;  
   
   bgp_md5_set (peer);    bgp_md5_set (peer);
   
Line 1702  peer_group_delete (struct peer_group *group) Line 1771  peer_group_delete (struct peer_group *group)
   
   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))    for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
     {      {
       peer->group = NULL;  
       peer_delete (peer);        peer_delete (peer);
     }      }
   list_delete (group->peer);    list_delete (group->peer);
Line 1732  peer_group_remote_as_delete (struct peer_group *group) Line 1800  peer_group_remote_as_delete (struct peer_group *group)
   
   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))    for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
     {      {
       peer->group = NULL;  
       peer_delete (peer);        peer_delete (peer);
     }      }
   list_delete_all_node (group->peer);    list_delete_all_node (group->peer);
Line 1817  peer_group_bind (struct bgp *bgp, union sockunion *su, Line 1884  peer_group_bind (struct bgp *bgp, union sockunion *su,
   if (first_member)    if (first_member)
     {      {
       /* Advertisement-interval reset */        /* Advertisement-interval reset */
      if (peer_sort (group->conf) == BGP_PEER_IBGP)      if (! CHECK_FLAG (group->conf->config, PEER_CONFIG_ROUTEADV))
        group->conf->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;        {
      else          if (peer_sort (group->conf) == BGP_PEER_IBGP)
        group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;            group->conf->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
           else
             group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
         }
   
       /* ebgp-multihop reset */        /* ebgp-multihop reset */
       if (peer_sort (group->conf) == BGP_PEER_IBGP)        if (peer_sort (group->conf) == BGP_PEER_IBGP)
Line 1874  peer_group_bind (struct bgp *bgp, union sockunion *su, Line 1944  peer_group_bind (struct bgp *bgp, union sockunion *su,
   
   peer_group2peer_config_copy (group, peer, afi, safi);    peer_group2peer_config_copy (group, peer, afi, safi);
   
  if (peer->status == Established)  if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
     {      {
       peer->last_reset = PEER_DOWN_RMAP_BIND;        peer->last_reset = PEER_DOWN_RMAP_BIND;
       bgp_notify_send (peer, BGP_NOTIFY_CEASE,        bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 1917  peer_group_unbind (struct bgp *bgp, struct peer *peer, Line 1987  peer_group_unbind (struct bgp *bgp, struct peer *peer,
       peer_global_config_reset (peer);        peer_global_config_reset (peer);
     }      }
   
  if (peer->status == Established)  if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
     {      {
       peer->last_reset = PEER_DOWN_RMAP_UNBIND;        peer->last_reset = PEER_DOWN_RMAP_UNBIND;
       bgp_notify_send (peer, BGP_NOTIFY_CEASE,        bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 1928  peer_group_unbind (struct bgp *bgp, struct peer *peer, Line 1998  peer_group_unbind (struct bgp *bgp, struct peer *peer,
   
   return 0;    return 0;
 }  }
 
 static int
 bgp_startup_timer_expire (struct thread *thread)
 {
   struct bgp *bgp;
 
   bgp = THREAD_ARG (thread);
   bgp->t_startup = NULL;
 
   return 0;
 }
 
 /* BGP instance creation by `router bgp' commands. */  /* BGP instance creation by `router bgp' commands. */
 static struct bgp *  static struct bgp *
 bgp_create (as_t *as, const char *name)  bgp_create (as_t *as, const char *name)
Line 1968  bgp_create (as_t *as, const char *name) Line 2050  bgp_create (as_t *as, const char *name)
   bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;    bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
   bgp->restart_time = BGP_DEFAULT_RESTART_TIME;    bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
   bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;    bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
     bgp_flag_set (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
   
   bgp->as = *as;    bgp->as = *as;
   
   if (name)    if (name)
     bgp->name = strdup (name);      bgp->name = strdup (name);
   
     THREAD_TIMER_ON (bm->master, bgp->t_startup, bgp_startup_timer_expire,
                      bgp, bgp->restart_time);
   
   return bgp;    return bgp;
 }  }
   
Line 1981  bgp_create (as_t *as, const char *name) Line 2067  bgp_create (as_t *as, const char *name)
 struct bgp *  struct bgp *
 bgp_get_default (void)  bgp_get_default (void)
 {  {
  if (bm->bgp->head)  if (bm && bm->bgp && bm->bgp->head)
     return (listgetdata (listhead (bm->bgp)));      return (listgetdata (listhead (bm->bgp)));
   return NULL;    return NULL;
 }  }
Line 2085  bgp_delete (struct bgp *bgp) Line 2171  bgp_delete (struct bgp *bgp)
 {  {
   struct peer *peer;    struct peer *peer;
   struct peer_group *group;    struct peer_group *group;
  struct listnode *node;  struct listnode *node, *pnode;
  struct listnode *next;  struct listnode *next, *pnext;
   afi_t afi;    afi_t afi;
   int i;    int i;
   
     SET_FLAG(bgp->flags, BGP_FLAG_DELETING);
   
     THREAD_OFF (bgp->t_startup);
   
   /* Delete static route. */    /* Delete static route. */
   bgp_static_delete (bgp);    bgp_static_delete (bgp);
   
Line 2100  bgp_delete (struct bgp *bgp) Line 2190  bgp_delete (struct bgp *bgp)
         bgp_redistribute_unset (bgp, afi, i);          bgp_redistribute_unset (bgp, afi, i);
   
   for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))    for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
    peer_delete (peer);    {
       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
         {
           /* Send notify to remote peer. */
           bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
         }
   
         peer_delete (peer);
       }
   
   for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))    for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
    peer_group_delete (group);    {
       for (ALL_LIST_ELEMENTS (group->peer, pnode, pnext, peer))
         {
           if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
             {
               /* Send notify to remote peer. */
               bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
             }
         }
       peer_group_delete (group);
     }
   
   assert (listcount (bgp->rsclient) == 0);    assert (listcount (bgp->rsclient) == 0);
   
Line 2111  bgp_delete (struct bgp *bgp) Line 2219  bgp_delete (struct bgp *bgp)
     peer_delete(bgp->peer_self);      peer_delete(bgp->peer_self);
     bgp->peer_self = NULL;      bgp->peer_self = NULL;
   }    }
  
   /*
    * Free pending deleted routes. Unfortunately, it also has to process
    * all the pending activity for other instances of struct bgp.
    *
    * This call was added to achieve clean memory allocation at exit,
    * for the sake of valgrind.
    */
   bgp_process_queues_drain_immediate();
 
   /* Remove visibility via the master list - there may however still be    /* Remove visibility via the master list - there may however still be
    * routes to be processed still referencing the struct bgp.     * routes to be processed still referencing the struct bgp.
    */     */
Line 2165  bgp_free (struct bgp *bgp) Line 2282  bgp_free (struct bgp *bgp)
       }        }
   XFREE (MTYPE_BGP, bgp);    XFREE (MTYPE_BGP, bgp);
 }  }
 struct peer *  struct peer *
 peer_lookup (struct bgp *bgp, union sockunion *su)  peer_lookup (struct bgp *bgp, union sockunion *su)
 {  {
Line 2234  peer_lookup_with_open (union sockunion *su, as_t remot Line 2351  peer_lookup_with_open (union sockunion *su, as_t remot
     }      }
   return NULL;    return NULL;
 }  }
 /* If peer is configured at least one address family return 1. */  /* If peer is configured at least one address family return 1. */
 int  int
 peer_active (struct peer *peer)  peer_active (struct peer *peer)
Line 2242  peer_active (struct peer *peer) Line 2359  peer_active (struct peer *peer)
   if (peer->afc[AFI_IP][SAFI_UNICAST]    if (peer->afc[AFI_IP][SAFI_UNICAST]
       || peer->afc[AFI_IP][SAFI_MULTICAST]        || peer->afc[AFI_IP][SAFI_MULTICAST]
       || peer->afc[AFI_IP][SAFI_MPLS_VPN]        || peer->afc[AFI_IP][SAFI_MPLS_VPN]
         || peer->afc[AFI_IP][SAFI_ENCAP]
       || peer->afc[AFI_IP6][SAFI_UNICAST]        || peer->afc[AFI_IP6][SAFI_UNICAST]
      || peer->afc[AFI_IP6][SAFI_MULTICAST])      || peer->afc[AFI_IP6][SAFI_MULTICAST]
       || peer->afc[AFI_IP6][SAFI_MPLS_VPN]
       || peer->afc[AFI_IP6][SAFI_ENCAP])
     return 1;      return 1;
   return 0;    return 0;
 }  }
Line 2255  peer_active_nego (struct peer *peer) Line 2375  peer_active_nego (struct peer *peer)
   if (peer->afc_nego[AFI_IP][SAFI_UNICAST]    if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
       || peer->afc_nego[AFI_IP][SAFI_MULTICAST]        || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
       || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]        || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
         || peer->afc_nego[AFI_IP][SAFI_ENCAP]
       || peer->afc_nego[AFI_IP6][SAFI_UNICAST]        || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
      || peer->afc_nego[AFI_IP6][SAFI_MULTICAST])      || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
       || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
       || peer->afc_nego[AFI_IP6][SAFI_ENCAP])
     return 1;      return 1;
   return 0;    return 0;
 }  }
 /* peer_flag_change_type. */  /* peer_flag_change_type. */
 enum peer_change_type  enum peer_change_type
 {  {
Line 2277  peer_change_action (struct peer *peer, afi_t afi, safi Line 2400  peer_change_action (struct peer *peer, afi_t afi, safi
   if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     return;      return;
   
     if (peer->status != Established)
       return;
   
   if (type == peer_change_reset)    if (type == peer_change_reset)
     bgp_notify_send (peer, BGP_NOTIFY_CEASE,      bgp_notify_send (peer, BGP_NOTIFY_CEASE,
                      BGP_NOTIFY_CEASE_CONFIG_CHANGE);                       BGP_NOTIFY_CEASE_CONFIG_CHANGE);
Line 2336  static const struct peer_flag_action peer_af_flag_acti Line 2462  static const struct peer_flag_action peer_af_flag_acti
     { PEER_FLAG_ORF_PREFIX_SM,            1, peer_change_reset },      { PEER_FLAG_ORF_PREFIX_SM,            1, peer_change_reset },
     { PEER_FLAG_ORF_PREFIX_RM,            1, peer_change_reset },      { PEER_FLAG_ORF_PREFIX_RM,            1, peer_change_reset },
     { PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED,  0, peer_change_reset_out },      { PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED,  0, peer_change_reset_out },
       { PEER_FLAG_NEXTHOP_SELF_ALL,         1, peer_change_reset_out },
     { 0, 0, 0 }      { 0, 0, 0 }
   };    };
   
Line 2411  peer_flag_modify_action (struct peer *peer, u_int32_t  Line 2538  peer_flag_modify_action (struct peer *peer, u_int32_t 
       if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))        if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
         peer_nsf_stop (peer);          peer_nsf_stop (peer);
   
          if (peer->status == Established)          if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
             bgp_notify_send (peer, BGP_NOTIFY_CEASE,              bgp_notify_send (peer, BGP_NOTIFY_CEASE,
                              BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);                               BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
           else            else
Line 2423  peer_flag_modify_action (struct peer *peer, u_int32_t  Line 2550  peer_flag_modify_action (struct peer *peer, u_int32_t 
           BGP_EVENT_ADD (peer, BGP_Stop);            BGP_EVENT_ADD (peer, BGP_Stop);
         }          }
     }      }
  else if (peer->status == Established)  else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
     {      {
       if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)        if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
         peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;          peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
Line 2676  peer_af_flag_unset (struct peer *peer, afi_t afi, safi Line 2803  peer_af_flag_unset (struct peer *peer, afi_t afi, safi
 {  {
   return peer_af_flag_modify (peer, afi, safi, flag, 0);    return peer_af_flag_modify (peer, afi, safi, flag, 0);
 }  }
 /* EBGP multihop configuration. */  /* EBGP multihop configuration. */
 int  int
 peer_ebgp_multihop_set (struct peer *peer, int ttl)  peer_ebgp_multihop_set (struct peer *peer, int ttl)
Line 2775  peer_ebgp_multihop_unset (struct peer *peer) Line 2902  peer_ebgp_multihop_unset (struct peer *peer)
     }      }
   return 0;    return 0;
 }  }
 /* Neighbor description. */  /* Neighbor description. */
 int  int
 peer_description_set (struct peer *peer, char *desc)  peer_description_set (struct peer *peer, char *desc)
Line 2798  peer_description_unset (struct peer *peer) Line 2925  peer_description_unset (struct peer *peer)
   
   return 0;    return 0;
 }  }
 /* Neighbor update-source. */  /* Neighbor update-source. */
 int  int
 peer_update_source_if_set (struct peer *peer, const char *ifname)  peer_update_source_if_set (struct peer *peer, const char *ifname)
Line 2826  peer_update_source_if_set (struct peer *peer, const ch Line 2953  peer_update_source_if_set (struct peer *peer, const ch
   
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {      {
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;           peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 2858  peer_update_source_if_set (struct peer *peer, const ch Line 2985  peer_update_source_if_set (struct peer *peer, const ch
   
       peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);        peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;           peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 2895  peer_update_source_addr_set (struct peer *peer, union  Line 3022  peer_update_source_addr_set (struct peer *peer, union 
   
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {      {
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;           peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 2926  peer_update_source_addr_set (struct peer *peer, union  Line 3053  peer_update_source_addr_set (struct peer *peer, union 
   
       peer->update_source = sockunion_dup (su);        peer->update_source = sockunion_dup (su);
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;           peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 2977  peer_update_source_unset (struct peer *peer) Line 3104  peer_update_source_unset (struct peer *peer)
   
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {      {
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;           peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 3007  peer_update_source_unset (struct peer *peer) Line 3134  peer_update_source_unset (struct peer *peer)
           peer->update_if = NULL;            peer->update_if = NULL;
         }          }
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;           peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 3018  peer_update_source_unset (struct peer *peer) Line 3145  peer_update_source_unset (struct peer *peer)
     }      }
   return 0;    return 0;
 }  }
 int  int
 peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,  peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
                             const char *rmap)                              const char *rmap)
Line 3123  peer_default_originate_unset (struct peer *peer, afi_t Line 3250  peer_default_originate_unset (struct peer *peer, afi_t
     }      }
   return 0;    return 0;
 }  }
 int  int
 peer_port_set (struct peer *peer, u_int16_t port)  peer_port_set (struct peer *peer, u_int16_t port)
 {  {
Line 3137  peer_port_unset (struct peer *peer) Line 3264  peer_port_unset (struct peer *peer)
   peer->port = BGP_PORT_DEFAULT;    peer->port = BGP_PORT_DEFAULT;
   return 0;    return 0;
 }  }
 /* neighbor weight. */  /* neighbor weight. */
 int  int
 peer_weight_set (struct peer *peer, u_int16_t weight)  peer_weight_set (struct peer *peer, u_int16_t weight)
Line 3185  peer_weight_unset (struct peer *peer) Line 3312  peer_weight_unset (struct peer *peer)
     }      }
   return 0;    return 0;
 }  }
 int  int
 peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)  peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
 {  {
Line 3255  peer_timers_unset (struct peer *peer) Line 3382  peer_timers_unset (struct peer *peer)
   
   return 0;    return 0;
 }  }
 int  int
 peer_timers_connect_set (struct peer *peer, u_int32_t connect)  peer_timers_connect_set (struct peer *peer, u_int32_t connect)
 {  {
     struct peer_group *group;
     struct listnode *node, *nnode;
   
   if (peer_group_active (peer))    if (peer_group_active (peer))
     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;      return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
   
Line 3272  peer_timers_connect_set (struct peer *peer, u_int32_t  Line 3402  peer_timers_connect_set (struct peer *peer, u_int32_t 
   /* Set value to timer setting. */    /* Set value to timer setting. */
   peer->v_connect = connect;    peer->v_connect = connect;
   
     if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
       return 0;
   
     /* peer-group member updates. */
     group = peer->group;
     for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
       {
         SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
         peer->connect = connect;
         peer->v_connect = connect;
       }
   return 0;    return 0;
 }  }
   
 int  int
 peer_timers_connect_unset (struct peer *peer)  peer_timers_connect_unset (struct peer *peer)
 {  {
     struct peer_group *group;
     struct listnode *node, *nnode;
   
   if (peer_group_active (peer))    if (peer_group_active (peer))
     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;      return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
   
Line 3288  peer_timers_connect_unset (struct peer *peer) Line 3432  peer_timers_connect_unset (struct peer *peer)
   /* Set timer setting to default value. */    /* Set timer setting to default value. */
   peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;    peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
   
  return 0;  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     return 0;
 
   /* peer-group member updates. */
   group = peer->group;
   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
     {
       UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
       peer->connect = 0;
       peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
     }
    return 0;
 }  }
 int  int
 peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)  peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)
 {  {
     struct peer_group *group;
     struct listnode *node, *nnode;
   
   if (peer_group_active (peer))    if (peer_group_active (peer))
     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;      return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
   
Line 3304  peer_advertise_interval_set (struct peer *peer, u_int3 Line 3462  peer_advertise_interval_set (struct peer *peer, u_int3
   peer->routeadv = routeadv;    peer->routeadv = routeadv;
   peer->v_routeadv = routeadv;    peer->v_routeadv = routeadv;
   
     if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
       return 0;
   
     /* peer-group member updates. */
     group = peer->group;
     for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
       {
         SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
         peer->routeadv = routeadv;
         peer->v_routeadv = routeadv;
       }
   
   return 0;    return 0;
 }  }
   
 int  int
 peer_advertise_interval_unset (struct peer *peer)  peer_advertise_interval_unset (struct peer *peer)
 {  {
     struct peer_group *group;
     struct listnode *node, *nnode;
   
   if (peer_group_active (peer))    if (peer_group_active (peer))
     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;      return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
   
Line 3320  peer_advertise_interval_unset (struct peer *peer) Line 3493  peer_advertise_interval_unset (struct peer *peer)
     peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;      peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
   else    else
     peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;      peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
   
     if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
       return 0;
   
     /* peer-group member updates. */
     group = peer->group;
     for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
       {
         UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
         peer->routeadv = 0;
   
         if (peer->sort == BGP_PEER_IBGP)
           peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
         else
           peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
       }
       
   return 0;    return 0;
 }  }
 /* neighbor interface */  /* neighbor interface */
 int  int
 peer_interface_set (struct peer *peer, const char *str)  peer_interface_set (struct peer *peer, const char *str)
Line 3344  peer_interface_unset (struct peer *peer) Line 3533  peer_interface_unset (struct peer *peer)
   
   return 0;    return 0;
 }  }
 /* Allow-as in.  */  /* Allow-as in.  */
 int  int
 peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)  peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
Line 3405  peer_allowas_in_unset (struct peer *peer, afi_t afi, s Line 3594  peer_allowas_in_unset (struct peer *peer, afi_t afi, s
     }      }
   return 0;    return 0;
 }  }
 int  int
 peer_local_as_set (struct peer *peer, as_t as, int no_prepend, int replace_as)  peer_local_as_set (struct peer *peer, as_t as, int no_prepend, int replace_as)
 {  {
Line 3446  peer_local_as_set (struct peer *peer, as_t as, int no_ Line 3635  peer_local_as_set (struct peer *peer, as_t as, int no_
   
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {      {
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;           peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 3472  peer_local_as_set (struct peer *peer, as_t as, int no_ Line 3661  peer_local_as_set (struct peer *peer, as_t as, int no_
       else        else
         UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);          UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;           peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 3503  peer_local_as_unset (struct peer *peer) Line 3692  peer_local_as_unset (struct peer *peer)
   
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {      {
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;           peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 3522  peer_local_as_unset (struct peer *peer) Line 3711  peer_local_as_unset (struct peer *peer)
       UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);        UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
       UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);        UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
        {         {
          peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;           peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
          bgp_notify_send (peer, BGP_NOTIFY_CEASE,           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
Line 3533  peer_local_as_unset (struct peer *peer) Line 3722  peer_local_as_unset (struct peer *peer)
     }      }
   return 0;    return 0;
 }  }
 /* Set password for authenticating with the peer. */  /* Set password for authenticating with the peer. */
 int  int
 peer_password_set (struct peer *peer, const char *password)  peer_password_set (struct peer *peer, const char *password)
Line 3556  peer_password_set (struct peer *peer, const char *pass Line 3745  peer_password_set (struct peer *peer, const char *pass
   
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {      {
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
          bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
       else        else
         BGP_EVENT_ADD (peer, BGP_Stop);          BGP_EVENT_ADD (peer, BGP_Stop);
                   
Line 3574  peer_password_set (struct peer *peer, const char *pass Line 3763  peer_password_set (struct peer *peer, const char *pass
               
       peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);        peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
         bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);          bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
       else        else
         BGP_EVENT_ADD (peer, BGP_Stop);          BGP_EVENT_ADD (peer, BGP_Stop);
Line 3602  peer_password_unset (struct peer *peer) Line 3791  peer_password_unset (struct peer *peer)
           && strcmp (peer->group->conf->password, peer->password) == 0)            && strcmp (peer->group->conf->password, peer->password) == 0)
         return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;          return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
         bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);          bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
       else        else
         BGP_EVENT_ADD (peer, BGP_Stop);          BGP_EVENT_ADD (peer, BGP_Stop);
Line 3625  peer_password_unset (struct peer *peer) Line 3814  peer_password_unset (struct peer *peer)
       if (!peer->password)        if (!peer->password)
         continue;          continue;
   
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
         bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);          bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
       else        else
         BGP_EVENT_ADD (peer, BGP_Stop);          BGP_EVENT_ADD (peer, BGP_Stop);
Line 3638  peer_password_unset (struct peer *peer) Line 3827  peer_password_unset (struct peer *peer)
   
   return 0;    return 0;
 }  }
 /* Set distribute list to the peer. */  /* Set distribute list to the peer. */
 int  int
 peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,   peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 
Line 3798  peer_distribute_update (struct access_list *access) Line 3987  peer_distribute_update (struct access_list *access)
         }          }
     }      }
 }  }
 /* Set prefix list to the peer. */  /* Set prefix list to the peer. */
 int  int
 peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct,   peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 
Line 3957  peer_prefix_list_update (struct prefix_list *plist) Line 4146  peer_prefix_list_update (struct prefix_list *plist)
         }          }
     }      }
 }  }
 int  int
 peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,  peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
                  const char *name)                   const char *name)
Line 4111  peer_aslist_update (void) Line 4300  peer_aslist_update (void)
         }          }
     }      }
 }  }
 /* Set route-map to the peer. */  /* Set route-map to the peer. */
 int  int
 peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct,   peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 
Line 4219  peer_route_map_unset (struct peer *peer, afi_t afi, sa Line 4408  peer_route_map_unset (struct peer *peer, afi_t afi, sa
     }      }
   return 0;    return 0;
 }  }
 /* Set unsuppress-map to the peer. */  /* Set unsuppress-map to the peer. */
 int  int
 peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi,   peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi, 
Line 4301  peer_unsuppress_map_unset (struct peer *peer, afi_t af Line 4490  peer_unsuppress_map_unset (struct peer *peer, afi_t af
     }      }
   return 0;    return 0;
 }  }
 int  int
 peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,  peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
                          u_int32_t max, u_char threshold,                           u_int32_t max, u_char threshold,
Line 4396  peer_maximum_prefix_unset (struct peer *peer, afi_t af Line 4585  peer_maximum_prefix_unset (struct peer *peer, afi_t af
     }      }
   return 0;    return 0;
 }  }
 static int is_ebgp_multihop_configured (struct peer *peer)
 {
   struct peer_group *group;
   struct listnode *node, *nnode;
   struct peer *peer1;
 
   if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {
       group = peer->group;
       if ((peer_sort(peer) != BGP_PEER_IBGP) &&
           (group->conf->ttl != 1))
         return 1;
 
       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
         {
           if ((peer_sort (peer1) != BGP_PEER_IBGP) &&
               (peer1->ttl != 1))
             return 1;
         }
     }
   else
     {
       if ((peer_sort(peer) != BGP_PEER_IBGP) &&
           (peer->ttl != 1))
         return 1;
     }
   return 0;
 }
 
 /* Set # of hops between us and BGP peer. */  /* Set # of hops between us and BGP peer. */
 int  int
 peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)  peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
 {  {
   struct peer_group *group;    struct peer_group *group;
   struct listnode *node, *nnode;    struct listnode *node, *nnode;
   struct peer *peer1;  
   int ret;    int ret;
   
   zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host);    zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host);
   
   if (peer->sort == BGP_PEER_IBGP)  
     return BGP_ERR_NO_IBGP_WITH_TTLHACK;  
   
   /* We cannot configure ttl-security hops when ebgp-multihop is already    /* We cannot configure ttl-security hops when ebgp-multihop is already
      set.  For non peer-groups, the check is simple.  For peer-groups, it's       set.  For non peer-groups, the check is simple.  For peer-groups, it's
      slightly messy, because we need to check both the peer-group structure       slightly messy, because we need to check both the peer-group structure
Line 4419  peer_ttl_security_hops_set (struct peer *peer, int gts Line 4633  peer_ttl_security_hops_set (struct peer *peer, int gts
      mess of this configuration parameter, and OpenBGPD got it right.       mess of this configuration parameter, and OpenBGPD got it right.
   */    */
       
  if (peer->gtsm_hops == 0) {  if (peer->gtsm_hops == 0)
    if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    {
      {      if (is_ebgp_multihop_configured (peer))
        group = peer->group;        return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
        if (group->conf->ttl != 1) 
          return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; 
   
        for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))      /* specify MAXTTL on outgoing packets */
          {      /* Routine handles iBGP peers correctly */
            if (peer1->sort == BGP_PEER_IBGP)      ret = peer_ebgp_multihop_set (peer, MAXTTL);
              continue;      if (ret != 0)
        return ret;
            if (peer1->ttl != 1)    }
              return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; 
          } 
      } 
    else 
      { 
        if (peer->ttl != 1) 
          return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; 
      } 
    /* specify MAXTTL on outgoing packets */ 
    ret = peer_ebgp_multihop_set (peer, MAXTTL); 
    if (ret != 0) 
      return ret; 
  } 
       
   peer->gtsm_hops = gtsm_hops;    peer->gtsm_hops = gtsm_hops;
   
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {      {
      if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)      if (peer->fd >= 0)
         sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - gtsm_hops);          sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - gtsm_hops);
     }      }
   else    else
Line 4458  peer_ttl_security_hops_set (struct peer *peer, int gts Line 4657  peer_ttl_security_hops_set (struct peer *peer, int gts
       group = peer->group;        group = peer->group;
       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))        for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
         {          {
           if (peer->sort == BGP_PEER_IBGP)  
             continue;  
   
           peer->gtsm_hops = group->conf->gtsm_hops;            peer->gtsm_hops = group->conf->gtsm_hops;
   
           /* Change setting of existing peer            /* Change setting of existing peer
Line 4495  peer_ttl_security_hops_unset (struct peer *peer) Line 4691  peer_ttl_security_hops_unset (struct peer *peer)
   
   zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host);    zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host);
   
   if (peer->sort == BGP_PEER_IBGP)  
       return 0;  
   
   /* if a peer-group member, then reset to peer-group default rather than 0 */    /* if a peer-group member, then reset to peer-group default rather than 0 */
   if (peer_group_active (peer))    if (peer_group_active (peer))
     peer->gtsm_hops = peer->group->conf->gtsm_hops;      peer->gtsm_hops = peer->group->conf->gtsm_hops;
Line 4507  peer_ttl_security_hops_unset (struct peer *peer) Line 4700  peer_ttl_security_hops_unset (struct peer *peer)
   opeer = peer;    opeer = peer;
   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
     {      {
      if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)      if (peer->fd >= 0)
         sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);          sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
     }      }
   else    else
Line 4515  peer_ttl_security_hops_unset (struct peer *peer) Line 4708  peer_ttl_security_hops_unset (struct peer *peer)
       group = peer->group;        group = peer->group;
       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))        for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
         {          {
           if (peer->sort == BGP_PEER_IBGP)  
             continue;  
   
           peer->gtsm_hops = 0;            peer->gtsm_hops = 0;
                       
           if (peer->fd >= 0)            if (peer->fd >= 0)
Line 4527  peer_ttl_security_hops_unset (struct peer *peer) Line 4717  peer_ttl_security_hops_unset (struct peer *peer)
   
   return peer_ebgp_multihop_unset (opeer);    return peer_ebgp_multihop_unset (opeer);
 }  }
 int  int
 peer_clear (struct peer *peer)  peer_clear (struct peer *peer)
 {  {
Line 4548  peer_clear (struct peer *peer) Line 4738  peer_clear (struct peer *peer)
         }          }
   
       peer->v_start = BGP_INIT_START_TIMER;        peer->v_start = BGP_INIT_START_TIMER;
      if (peer->status == Established)      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
         bgp_notify_send (peer, BGP_NOTIFY_CEASE,          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
                          BGP_NOTIFY_CEASE_ADMIN_RESET);                           BGP_NOTIFY_CEASE_ADMIN_RESET);
       else        else
Line 4567  peer_clear_soft (struct peer *peer, afi_t afi, safi_t  Line 4757  peer_clear_soft (struct peer *peer, afi_t afi, safi_t 
   if (! peer->afc[afi][safi])    if (! peer->afc[afi][safi])
     return BGP_ERR_AF_UNCONFIGURED;      return BGP_ERR_AF_UNCONFIGURED;
   
     peer->rtt = sockopt_tcp_rtt (peer->fd);
   
   if (stype == BGP_CLEAR_SOFT_RSCLIENT)    if (stype == BGP_CLEAR_SOFT_RSCLIENT)
     {      {
       if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))        if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
Line 4632  peer_clear_soft (struct peer *peer, afi_t afi, safi_t  Line 4824  peer_clear_soft (struct peer *peer, afi_t afi, safi_t 
     }      }
   return 0;    return 0;
 }  }
 /* Display peer uptime.*/  /* Display peer uptime.*/
 /* XXX: why does this function return char * when it takes buffer? */  /* XXX: why does this function return char * when it takes buffer? */
 char *  char *
Line 4661  peer_uptime (time_t uptime2, char *buf, size_t len) Line 4853  peer_uptime (time_t uptime2, char *buf, size_t len)
   uptime1 = bgp_clock ();    uptime1 = bgp_clock ();
   uptime1 -= uptime2;    uptime1 -= uptime2;
   tm = gmtime (&uptime1);    tm = gmtime (&uptime1);
  
   /* Making formatted timer strings. */    /* Making formatted timer strings. */
 #define ONE_DAY_SECOND 60*60*24  #define ONE_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7#define ONE_WEEK_SECOND ONE_DAY_SECOND*7
 #define ONE_YEAR_SECOND ONE_DAY_SECOND*365
   
   if (uptime1 < ONE_DAY_SECOND)    if (uptime1 < ONE_DAY_SECOND)
     snprintf (buf, len, "%02d:%02d:%02d",       snprintf (buf, len, "%02d:%02d:%02d", 
Line 4672  peer_uptime (time_t uptime2, char *buf, size_t len) Line 4865  peer_uptime (time_t uptime2, char *buf, size_t len)
   else if (uptime1 < ONE_WEEK_SECOND)    else if (uptime1 < ONE_WEEK_SECOND)
     snprintf (buf, len, "%dd%02dh%02dm",       snprintf (buf, len, "%dd%02dh%02dm", 
               tm->tm_yday, tm->tm_hour, tm->tm_min);                tm->tm_yday, tm->tm_hour, tm->tm_min);
  else  else if (uptime1 < ONE_YEAR_SECOND)
     snprintf (buf, len, "%02dw%dd%02dh",       snprintf (buf, len, "%02dw%dd%02dh", 
               tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);                tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
     else
       snprintf (buf, len, "%02dy%02dw%dd", 
                 tm->tm_year - 70, tm->tm_yday/7, 
                 tm->tm_yday - ((tm->tm_yday/7) * 7));
   return buf;    return buf;
 }  }
 static void  static void
 bgp_config_write_filter (struct vty *vty, struct peer *peer,  bgp_config_write_filter (struct vty *vty, struct peer *peer,
                          afi_t afi, safi_t safi)                           afi_t afi, safi_t safi)
Line 4840  bgp_config_write_peer (struct vty *vty, struct bgp *bg Line 5037  bgp_config_write_peer (struct vty *vty, struct bgp *bg
                    VTY_NEWLINE);                     VTY_NEWLINE);
   
      /* ttl-security hops */       /* ttl-security hops */
      if (peer->sort != BGP_PEER_IBGP && peer->gtsm_hops != 0)      if (peer->gtsm_hops != 0)
         if (! peer_group_active (peer) || g_peer->gtsm_hops != peer->gtsm_hops)          if (! peer_group_active (peer) || g_peer->gtsm_hops != peer->gtsm_hops)
           vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,            vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,
                    peer->gtsm_hops, VTY_NEWLINE);                     peer->gtsm_hops, VTY_NEWLINE);
Line 4866  bgp_config_write_peer (struct vty *vty, struct bgp *bg Line 5063  bgp_config_write_peer (struct vty *vty, struct bgp *bg
                    VTY_NEWLINE);                     VTY_NEWLINE);
   
       /* advertisement-interval */        /* advertisement-interval */
      if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV))      if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV) &&
           ! peer_group_active (peer))
         vty_out (vty, " neighbor %s advertisement-interval %d%s",          vty_out (vty, " neighbor %s advertisement-interval %d%s",
                  addr, peer->v_routeadv, VTY_NEWLINE);                    addr, peer->v_routeadv, VTY_NEWLINE); 
   
Line 4876  bgp_config_write_peer (struct vty *vty, struct bgp *bg Line 5074  bgp_config_write_peer (struct vty *vty, struct bgp *bg
           vty_out (vty, " neighbor %s timers %d %d%s", addr,             vty_out (vty, " neighbor %s timers %d %d%s", addr, 
           peer->keepalive, peer->holdtime, VTY_NEWLINE);            peer->keepalive, peer->holdtime, VTY_NEWLINE);
   
      if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT))      if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT) &&
           ! peer_group_active (peer))
           vty_out (vty, " neighbor %s timers connect %d%s", addr,             vty_out (vty, " neighbor %s timers connect %d%s", addr, 
           peer->connect, VTY_NEWLINE);            peer->connect, VTY_NEWLINE);
   
Line 4970  bgp_config_write_peer (struct vty *vty, struct bgp *bg Line 5169  bgp_config_write_peer (struct vty *vty, struct bgp *bg
   /* Nexthop self. */    /* Nexthop self. */
   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)    if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
       && ! peer->af_group[afi][safi])        && ! peer->af_group[afi][safi])
    vty_out (vty, " neighbor %s next-hop-self%s", addr, VTY_NEWLINE);    vty_out (vty, " neighbor %s next-hop-self%s%s", addr,
              peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF_ALL) ?
              " all" : "", VTY_NEWLINE);
   
   /* Remove private AS. */    /* Remove private AS. */
   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)    if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
Line 5107  bgp_config_write_family_header (struct vty *vty, afi_t Line 5308  bgp_config_write_family_header (struct vty *vty, afi_t
       if (safi == SAFI_MULTICAST)        if (safi == SAFI_MULTICAST)
         vty_out (vty, "ipv4 multicast");          vty_out (vty, "ipv4 multicast");
       else if (safi == SAFI_MPLS_VPN)        else if (safi == SAFI_MPLS_VPN)
        vty_out (vty, "vpnv4 unicast");        vty_out (vty, "vpnv4");
       else if (safi == SAFI_ENCAP)
         vty_out (vty, "encap");
     }      }
   else if (afi == AFI_IP6)    else if (afi == AFI_IP6)
     {      {
      vty_out (vty, "ipv6");      if (safi == SAFI_MPLS_VPN)
              vty_out (vty, "vpnv6");
      if (safi == SAFI_MULTICAST)      else if (safi == SAFI_ENCAP)
        vty_out (vty, " multicast");        vty_out (vty, "encapv6");
       else
         {
           vty_out (vty, "ipv6");
           if (safi == SAFI_MULTICAST)
             vty_out (vty, " multicast");
         }
     }      }
   
   vty_out (vty, "%s", VTY_NEWLINE);    vty_out (vty, "%s", VTY_NEWLINE);
Line 5218  bgp_config_write (struct vty *vty) Line 5427  bgp_config_write (struct vty *vty)
                  VTY_NEWLINE);                   VTY_NEWLINE);
   
       /* BGP log-neighbor-changes. */        /* BGP log-neighbor-changes. */
      if (bgp_flag_check (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))      if (!bgp_flag_check (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
        vty_out (vty, " bgp log-neighbor-changes%s", VTY_NEWLINE);        vty_out (vty, " no bgp log-neighbor-changes%s", VTY_NEWLINE);
   
       /* BGP configuration. */        /* BGP configuration. */
       if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED))        if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
Line 5281  bgp_config_write (struct vty *vty) Line 5490  bgp_config_write (struct vty *vty)
         vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);          vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
       if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))        if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
         vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);          vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
         if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
           vty_out (vty, " bgp bestpath as-path multipath-relax%s", VTY_NEWLINE);
         }
       if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID))        if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID))
         vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE);          vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE);
       if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)        if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
Line 5347  bgp_config_write (struct vty *vty) Line 5559  bgp_config_write (struct vty *vty)
       /* IPv4 VPN configuration.  */        /* IPv4 VPN configuration.  */
       write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);        write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);
   
         /* ENCAPv4 configuration.  */
         write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_ENCAP);
   
       /* IPv6 unicast configuration.  */        /* IPv6 unicast configuration.  */
       write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST);        write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST);
   
       /* IPv6 multicast configuration.  */        /* IPv6 multicast configuration.  */
       write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);        write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
   
         /* IPv6 VPN configuration.  */
         write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MPLS_VPN);
   
         /* ENCAPv6 configuration.  */
         write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_ENCAP);
   
         vty_out (vty, " exit%s", VTY_NEWLINE);
   
       write++;        write++;
     }      }
   return write;    return write;
Line 5371  bgp_master_init (void) Line 5594  bgp_master_init (void)
   bm->start_time = bgp_clock ();    bm->start_time = bgp_clock ();
 }  }
   
 void  void
 bgp_init (void)  bgp_init (void)
 {  {
Line 5379  bgp_init (void) Line 5602  bgp_init (void)
   bgp_vty_init ();    bgp_vty_init ();
   
   /* Init zebra. */    /* Init zebra. */
  bgp_zebra_init ();  bgp_zebra_init (bm->master);
   
   /* BGP inits. */    /* BGP inits. */
   bgp_attr_init ();    bgp_attr_init ();
Line 5390  bgp_init (void) Line 5613  bgp_init (void)
   bgp_address_init ();    bgp_address_init ();
   bgp_scan_init ();    bgp_scan_init ();
   bgp_mplsvpn_init ();    bgp_mplsvpn_init ();
     bgp_encap_init ();
   
   /* Access list initialize. */    /* Access list initialize. */
   access_list_init ();    access_list_init ();

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>