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

version 1.1.1.4, 2013/07/21 23:54:37 version 1.1.1.5, 2016/11/02 10:09:10
Line 28  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 28  Software Foundation, Inc., 59 Temple Place - Suite 330
 #include "log.h"  #include "log.h"
 #include "memory.h"  #include "memory.h"
 #include "sockunion.h"          /* for inet_ntop () */  #include "sockunion.h"          /* for inet_ntop () */
   #include "sockopt.h"
 #include "linklist.h"  #include "linklist.h"
 #include "plist.h"  #include "plist.h"
   #include "filter.h"
   
 #include "bgpd/bgpd.h"  #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"  #include "bgpd/bgp_table.h"
Line 45  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 47  Software Foundation, Inc., 59 Temple Place - Suite 330
 #include "bgpd/bgp_ecommunity.h"  #include "bgpd/bgp_ecommunity.h"
 #include "bgpd/bgp_network.h"  #include "bgpd/bgp_network.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_vty.h"  #include "bgpd/bgp_vty.h"
   
 int stream_put_prefix (struct stream *, struct prefix *);  int stream_put_prefix (struct stream *, struct prefix *);
 /* Set up BGP packet marker and packet type. */  /* Set up BGP packet marker and packet type. */
 static int  static int
 bgp_packet_set_marker (struct stream *s, u_char type)  bgp_packet_set_marker (struct stream *s, u_char type)
Line 142  static struct stream * Line 145  static struct stream *
 bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)  bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
 {  {
   struct stream *s;    struct stream *s;
     struct stream *snlri;
   struct bgp_adj_out *adj;    struct bgp_adj_out *adj;
   struct bgp_advertise *adv;    struct bgp_advertise *adv;
   struct stream *packet;    struct stream *packet;
   struct bgp_node *rn = NULL;    struct bgp_node *rn = NULL;
   struct bgp_info *binfo = NULL;    struct bgp_info *binfo = NULL;
   bgp_size_t total_attr_len = 0;    bgp_size_t total_attr_len = 0;
  unsigned long pos;  unsigned long attrlen_pos = 0;
   size_t mpattrlen_pos = 0;
   size_t mpattr_pos = 0;
   
   s = peer->work;    s = peer->work;
   stream_reset (s);    stream_reset (s);
     snlri = peer->scratch;
     stream_reset (snlri);
   
  adv = FIFO_HEAD (&peer->sync[afi][safi]->update);  adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
   
   while (adv)    while (adv)
     {      {
Line 164  bgp_update_packet (struct peer *peer, afi_t afi, safi_ Line 172  bgp_update_packet (struct peer *peer, afi_t afi, safi_
         binfo = adv->binfo;          binfo = adv->binfo;
   
       /* When remaining space can't include NLRI and it's length.  */        /* When remaining space can't include NLRI and it's length.  */
      if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))      if (STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) <=
           (BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size(afi,safi,&rn->p)))
         break;          break;
   
       /* If packet is empty, set attribute. */        /* If packet is empty, set attribute. */
Line 173  bgp_update_packet (struct peer *peer, afi_t afi, safi_ Line 182  bgp_update_packet (struct peer *peer, afi_t afi, safi_
           struct prefix_rd *prd = NULL;            struct prefix_rd *prd = NULL;
           u_char *tag = NULL;            u_char *tag = NULL;
           struct peer *from = NULL;            struct peer *from = NULL;
          
           if (rn->prn)            if (rn->prn)
             prd = (struct prefix_rd *) &rn->prn->p;              prd = (struct prefix_rd *) &rn->prn->p;
           if (binfo)            if (binfo)
Line 182  bgp_update_packet (struct peer *peer, afi_t afi, safi_ Line 191  bgp_update_packet (struct peer *peer, afi_t afi, safi_
               if (binfo->extra)                if (binfo->extra)
                 tag = binfo->extra->tag;                  tag = binfo->extra->tag;
             }              }
          
           /* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
            * one byte message type.
            */
           bgp_packet_set_marker (s, BGP_MSG_UPDATE);            bgp_packet_set_marker (s, BGP_MSG_UPDATE);
          stream_putw (s, 0);           
          pos = stream_get_endp (s);          /* 2: withdrawn routes length */
           stream_putw (s, 0);            stream_putw (s, 0);
          total_attr_len = bgp_packet_attribute (NULL, peer, s, 
           /* 3: total attributes length - attrlen_pos stores the position */
           attrlen_pos = stream_get_endp (s);
           stream_putw (s, 0);
 
           /* 4: if there is MP_REACH_NLRI attribute, that should be the first
            * attribute, according to draft-ietf-idr-error-handling. Save the
            * position.
            */
           mpattr_pos = stream_get_endp(s);
 
           /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
           total_attr_len = bgp_packet_attribute (NULL, peer, s,
                                                  adv->baa->attr,                                                   adv->baa->attr,
                                                 &rn->p, afi, safi,                                                  ((afi == AFI_IP && safi == SAFI_UNICAST) ?
                                                   &rn->p : NULL),
                                                  afi, safi,
                                                  from, prd, tag);                                                   from, prd, tag);
           stream_putw_at (s, pos, total_attr_len);  
         }          }
   
       if (afi == AFI_IP && safi == SAFI_UNICAST)        if (afi == AFI_IP && safi == SAFI_UNICAST)
         stream_put_prefix (s, &rn->p);          stream_put_prefix (s, &rn->p);
            else
         {
           /* Encode the prefix in MP_REACH_NLRI attribute */
           struct prefix_rd *prd = NULL;
           u_char *tag = NULL;
 
           if (rn->prn)
             prd = (struct prefix_rd *) &rn->prn->p;
           if (binfo && binfo->extra)
             tag = binfo->extra->tag;
 
           if (stream_empty(snlri))
             mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi,
                                                     adv->baa->attr);
           bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, tag);
         }
       if (BGP_DEBUG (update, UPDATE_OUT))        if (BGP_DEBUG (update, UPDATE_OUT))
         {          {
           char buf[INET6_BUFSIZ];            char buf[INET6_BUFSIZ];
Line 216  bgp_update_packet (struct peer *peer, afi_t afi, safi_ Line 256  bgp_update_packet (struct peer *peer, afi_t afi, safi_
       adj->attr = bgp_attr_intern (adv->baa->attr);        adj->attr = bgp_attr_intern (adv->baa->attr);
   
       adv = bgp_advertise_clean (peer, adj, afi, safi);        adv = bgp_advertise_clean (peer, adj, afi, safi);
   
       if (! (afi == AFI_IP && safi == SAFI_UNICAST))  
         break;  
     }      }
         
   if (! stream_empty (s))    if (! stream_empty (s))
     {      {
      bgp_packet_set_size (s);      if (!stream_empty(snlri))
      packet = stream_dup (s);        {
           bgp_packet_mpattr_end(snlri, mpattrlen_pos);
           total_attr_len += stream_get_endp(snlri);
         }
 
       /* set the total attribute length correctly */
       stream_putw_at (s, attrlen_pos, total_attr_len);
 
       if (!stream_empty(snlri))
         packet = stream_dupcat(s, snlri, mpattr_pos);
       else
         packet = stream_dup (s);
       bgp_packet_set_size (packet);
       bgp_packet_add (peer, packet);        bgp_packet_add (peer, packet);
       BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);        BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
       stream_reset (s);        stream_reset (s);
         stream_reset (snlri);
       return packet;        return packet;
     }      }
   return NULL;    return NULL;
Line 237  static struct stream * Line 287  static struct stream *
 bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)  bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
 {  {
   struct stream *s;    struct stream *s;
   struct stream *packet;  
   
   if (DISABLE_BGP_ANNOUNCE)    if (DISABLE_BGP_ANNOUNCE)
     return NULL;      return NULL;
Line 270  bgp_update_packet_eor (struct peer *peer, afi_t afi, s Line 319  bgp_update_packet_eor (struct peer *peer, afi_t afi, s
     }      }
   
   bgp_packet_set_size (s);    bgp_packet_set_size (s);
  packet = stream_dup (s);  bgp_packet_add (peer, s);
  bgp_packet_add (peer, packet);  return s;
  stream_free (s); 
  return packet; 
 }  }
   
 /* Make BGP withdraw packet.  */  /* Make BGP withdraw packet.  */
   /* For ipv4 unicast:
      16-octet marker | 2-octet length | 1-octet type |
       2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0)
   */
   /* For other afi/safis:
      16-octet marker | 2-octet length | 1-octet type |
       2-octet withdrawn route length (=0) | 2-octet attrlen |
        mp_unreach attr type | attr len | afi | safi | withdrawn prefixes
   */
 static struct stream *  static struct stream *
 bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)  bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
 {  {
Line 285  bgp_withdraw_packet (struct peer *peer, afi_t afi, saf Line 341  bgp_withdraw_packet (struct peer *peer, afi_t afi, saf
   struct bgp_adj_out *adj;    struct bgp_adj_out *adj;
   struct bgp_advertise *adv;    struct bgp_advertise *adv;
   struct bgp_node *rn;    struct bgp_node *rn;
   unsigned long pos;  
   bgp_size_t unfeasible_len;    bgp_size_t unfeasible_len;
   bgp_size_t total_attr_len;    bgp_size_t total_attr_len;
     size_t mp_start = 0;
     size_t attrlen_pos = 0;
     size_t mplen_pos = 0;
     u_char first_time = 1;
   
   s = peer->work;    s = peer->work;
   stream_reset (s);    stream_reset (s);
   
  while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)  while ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
     {      {
       assert (adv->rn);        assert (adv->rn);
       adj = adv->adj;        adj = adv->adj;
       rn = adv->rn;        rn = adv->rn;
   
      if (STREAM_REMAIN (s)       if (STREAM_REMAIN (s)
           < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))            < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
         break;          break;
   
       if (stream_empty (s))        if (stream_empty (s))
         {          {
           bgp_packet_set_marker (s, BGP_MSG_UPDATE);            bgp_packet_set_marker (s, BGP_MSG_UPDATE);
          stream_putw (s, 0);          stream_putw (s, 0); /* unfeasible routes length */
         }          }
         else
           first_time = 0;
   
       if (afi == AFI_IP && safi == SAFI_UNICAST)        if (afi == AFI_IP && safi == SAFI_UNICAST)
         stream_put_prefix (s, &rn->p);          stream_put_prefix (s, &rn->p);
       else        else
         {          {
           struct prefix_rd *prd = NULL;            struct prefix_rd *prd = NULL;
          
           if (rn->prn)            if (rn->prn)
             prd = (struct prefix_rd *) &rn->prn->p;              prd = (struct prefix_rd *) &rn->prn->p;
          pos = stream_get_endp (s);
          stream_putw (s, 0);          /* If first time, format the MP_UNREACH header */
          total_attr_len          if (first_time)
            = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);            {
                    attrlen_pos = stream_get_endp (s);
          /* Set total path attribute length. */              /* total attr length = 0 for now. reevaluate later */
          stream_putw_at (s, pos, total_attr_len);              stream_putw (s, 0);
               mp_start = stream_get_endp (s);
               mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
             }
 
           bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL);
         }          }
   
       if (BGP_DEBUG (update, UPDATE_OUT))        if (BGP_DEBUG (update, UPDATE_OUT))
Line 339  bgp_withdraw_packet (struct peer *peer, afi_t afi, saf Line 405  bgp_withdraw_packet (struct peer *peer, afi_t afi, saf
   
       bgp_adj_out_remove (rn, adj, peer, afi, safi);        bgp_adj_out_remove (rn, adj, peer, afi, safi);
       bgp_unlock_node (rn);        bgp_unlock_node (rn);
   
       if (! (afi == AFI_IP && safi == SAFI_UNICAST))  
         break;  
     }      }
   
   if (! stream_empty (s))    if (! stream_empty (s))
     {      {
       if (afi == AFI_IP && safi == SAFI_UNICAST)        if (afi == AFI_IP && safi == SAFI_UNICAST)
         {          {
          unfeasible_len           unfeasible_len
             = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;              = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
           stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);            stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
           stream_putw (s, 0);            stream_putw (s, 0);
         }          }
         else
           {
             /* Set the mp_unreach attr's length */
             bgp_packet_mpunreach_end(s, mplen_pos);
   
             /* Set total path attribute length. */
             total_attr_len = stream_get_endp(s) - mp_start;
             stream_putw_at (s, attrlen_pos, total_attr_len);
           }
       bgp_packet_set_size (s);        bgp_packet_set_size (s);
       packet = stream_dup (s);        packet = stream_dup (s);
       bgp_packet_add (peer, packet);        bgp_packet_add (peer, packet);
Line 368  bgp_default_update_send (struct peer *peer, struct att Line 440  bgp_default_update_send (struct peer *peer, struct att
                          afi_t afi, safi_t safi, struct peer *from)                           afi_t afi, safi_t safi, struct peer *from)
 {  {
   struct stream *s;    struct stream *s;
   struct stream *packet;  
   struct prefix p;    struct prefix p;
   unsigned long pos;    unsigned long pos;
   bgp_size_t total_attr_len;    bgp_size_t total_attr_len;
Line 378  bgp_default_update_send (struct peer *peer, struct att Line 449  bgp_default_update_send (struct peer *peer, struct att
   
   if (afi == AFI_IP)    if (afi == AFI_IP)
     str2prefix ("0.0.0.0/0", &p);      str2prefix ("0.0.0.0/0", &p);
 #ifdef HAVE_IPV6  
   else     else 
     str2prefix ("::/0", &p);      str2prefix ("::/0", &p);
 #endif /* HAVE_IPV6 */  
   
   /* Logging the attribute. */    /* Logging the attribute. */
   if (BGP_DEBUG (update, UPDATE_OUT))    if (BGP_DEBUG (update, UPDATE_OUT))
Line 419  bgp_default_update_send (struct peer *peer, struct att Line 488  bgp_default_update_send (struct peer *peer, struct att
   /* Set size. */    /* Set size. */
   bgp_packet_set_size (s);    bgp_packet_set_size (s);
   
   packet = stream_dup (s);  
   stream_free (s);  
   
   /* Dump packet if debug option is set. */    /* Dump packet if debug option is set. */
 #ifdef DEBUG  #ifdef DEBUG
   /* bgp_packet_dump (packet); */    /* bgp_packet_dump (packet); */
 #endif /* DEBUG */  #endif /* DEBUG */
   
   /* Add packet to the peer. */    /* Add packet to the peer. */
  bgp_packet_add (peer, packet);  bgp_packet_add (peer, s);
   
   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);    BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
 }  }
Line 437  void Line 503  void
 bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)  bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
 {  {
   struct stream *s;    struct stream *s;
   struct stream *packet;  
   struct prefix p;    struct prefix p;
  unsigned long pos;  unsigned long attrlen_pos = 0;
   unsigned long cp;    unsigned long cp;
   bgp_size_t unfeasible_len;    bgp_size_t unfeasible_len;
   bgp_size_t total_attr_len;    bgp_size_t total_attr_len;
     size_t mp_start = 0;
     size_t mplen_pos = 0;
   
   if (DISABLE_BGP_ANNOUNCE)    if (DISABLE_BGP_ANNOUNCE)
     return;      return;
   
   if (afi == AFI_IP)    if (afi == AFI_IP)
     str2prefix ("0.0.0.0/0", &p);      str2prefix ("0.0.0.0/0", &p);
 #ifdef HAVE_IPV6  
   else     else 
     str2prefix ("::/0", &p);      str2prefix ("::/0", &p);
 #endif /* HAVE_IPV6 */  
   
   total_attr_len = 0;    total_attr_len = 0;
   pos = 0;  
   
   if (BGP_DEBUG (update, UPDATE_OUT))    if (BGP_DEBUG (update, UPDATE_OUT))
     {      {
Line 490  bgp_default_withdraw_send (struct peer *peer, afi_t af Line 554  bgp_default_withdraw_send (struct peer *peer, afi_t af
     }      }
   else    else
     {      {
      pos = stream_get_endp (s);      attrlen_pos = stream_get_endp (s);
       stream_putw (s, 0);        stream_putw (s, 0);
      total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);      mp_start = stream_get_endp (s);
       mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
       bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL);
   
         /* Set the mp_unreach attr's length */
         bgp_packet_mpunreach_end(s, mplen_pos);
   
       /* Set total path attribute length. */        /* Set total path attribute length. */
      stream_putw_at (s, pos, total_attr_len);      total_attr_len = stream_get_endp(s) - mp_start;
       stream_putw_at (s, attrlen_pos, total_attr_len);
     }      }
   
   bgp_packet_set_size (s);    bgp_packet_set_size (s);
   
   packet = stream_dup (s);  
   stream_free (s);  
   
   /* Add packet to the peer. */    /* Add packet to the peer. */
  bgp_packet_add (peer, packet);  bgp_packet_add (peer, s);
   
   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);    BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
 }  }
Line 525  bgp_write_packet (struct peer *peer) Line 592  bgp_write_packet (struct peer *peer)
   for (afi = AFI_IP; afi < AFI_MAX; afi++)    for (afi = AFI_IP; afi < AFI_MAX; afi++)
     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)      for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
       {        {
        adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);        adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
         if (adv)          if (adv)
           {            {
             s = bgp_withdraw_packet (peer, afi, safi);              s = bgp_withdraw_packet (peer, afi, safi);
Line 537  bgp_write_packet (struct peer *peer) Line 604  bgp_write_packet (struct peer *peer)
   for (afi = AFI_IP; afi < AFI_MAX; afi++)    for (afi = AFI_IP; afi < AFI_MAX; afi++)
     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)      for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
       {        {
        adv = FIFO_HEAD (&peer->sync[afi][safi]->update);        adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
         if (adv)          if (adv)
           {            {
             if (adv->binfo && adv->binfo->uptime < peer->synctime)              if (adv->binfo && adv->binfo->uptime < peer->synctime)
               {                {
                 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)                  if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
                     && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)                      && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
                       && ! (CHECK_FLAG (adv->binfo->peer->cap,
                                         PEER_CAP_RESTART_BIT_RCV) &&
                             CHECK_FLAG (adv->binfo->peer->cap,
                                         PEER_CAP_RESTART_BIT_ADV))
                     && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)                      && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
                     && safi != SAFI_MPLS_VPN)                      && safi != SAFI_MPLS_VPN)
                   {                    {
Line 593  bgp_write_proceed (struct peer *peer) Line 664  bgp_write_proceed (struct peer *peer)
   
   for (afi = AFI_IP; afi < AFI_MAX; afi++)    for (afi = AFI_IP; afi < AFI_MAX; afi++)
     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)      for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
      if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)      if ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
         if (adv->binfo->uptime < peer->synctime)          if (adv->binfo->uptime < peer->synctime)
           return 1;            return 1;
   
Line 719  bgp_write_notify (struct peer *peer) Line 790  bgp_write_notify (struct peer *peer)
     return 0;      return 0;
   assert (stream_get_endp (s) >= BGP_HEADER_SIZE);    assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
   
   /* Put socket in blocking mode. */  
   val = fcntl (peer->fd, F_GETFL, 0);  
   fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK);  
   
   /* Stop collecting data within the socket */    /* Stop collecting data within the socket */
   sockopt_cork (peer->fd, 0);    sockopt_cork (peer->fd, 0);
   
     /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
      * we only care about getting a clean shutdown at this point. */
   ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));    ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
   
     /* only connection reset/close gets counted as TCP_fatal_error, failure
      * to write the entire NOTIFY doesn't get different FSM treatment */
   if (ret <= 0)    if (ret <= 0)
     {      {
       BGP_EVENT_ADD (peer, TCP_fatal_error);        BGP_EVENT_ADD (peer, TCP_fatal_error);
Line 903  bgp_notify_send_with_data (struct peer *peer, u_char c Line 975  bgp_notify_send_with_data (struct peer *peer, u_char c
             }              }
       }        }
     bgp_notify_print (peer, &bgp_notify, "sending");      bgp_notify_print (peer, &bgp_notify, "sending");
   
     if (bgp_notify.data)      if (bgp_notify.data)
      XFREE (MTYPE_TMP, bgp_notify.data);      {
         XFREE (MTYPE_TMP, bgp_notify.data);
         bgp_notify.data = NULL;
         bgp_notify.length = 0;
       }
   }    }
   
   if (BGP_DEBUG (normal, NORMAL))    if (BGP_DEBUG (normal, NORMAL))
Line 954  bgp_route_refresh_send (struct peer *peer, afi_t afi,  Line 1031  bgp_route_refresh_send (struct peer *peer, afi_t afi, 
                         u_char orf_type, u_char when_to_refresh, int remove)                          u_char orf_type, u_char when_to_refresh, int remove)
 {  {
   struct stream *s;    struct stream *s;
   struct stream *packet;  
   int length;    int length;
   struct bgp_filter *filter;    struct bgp_filter *filter;
   int orf_refresh = 0;    int orf_refresh = 0;
Line 1035  bgp_route_refresh_send (struct peer *peer, afi_t afi,  Line 1111  bgp_route_refresh_send (struct peer *peer, afi_t afi, 
                  BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);                   BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
     }      }
   
   /* Make real packet. */  
   packet = stream_dup (s);  
   stream_free (s);  
   
   /* Add packet to the peer. */    /* Add packet to the peer. */
  bgp_packet_add (peer, packet);  bgp_packet_add (peer, s);
   
   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);    BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
 }  }
Line 1051  bgp_capability_send (struct peer *peer, afi_t afi, saf Line 1123  bgp_capability_send (struct peer *peer, afi_t afi, saf
                      int capability_code, int action)                       int capability_code, int action)
 {  {
   struct stream *s;    struct stream *s;
   struct stream *packet;  
   int length;    int length;
   
   /* Adjust safi code. */    /* Adjust safi code. */
Line 1082  bgp_capability_send (struct peer *peer, afi_t afi, saf Line 1153  bgp_capability_send (struct peer *peer, afi_t afi, saf
   /* Set packet size. */    /* Set packet size. */
   length = bgp_packet_set_size (s);    length = bgp_packet_set_size (s);
   
   /* Make real packet. */  
   packet = stream_dup (s);  
   stream_free (s);  
   
   /* Add packet to the peer. */    /* Add packet to the peer. */
  bgp_packet_add (peer, packet);  bgp_packet_add (peer, s);
   
   if (BGP_DEBUG (normal, NORMAL))    if (BGP_DEBUG (normal, NORMAL))
     zlog_debug ("%s send message type %d, length (incl. header) %d",      zlog_debug ("%s send message type %d, length (incl. header) %d",
Line 1095  bgp_capability_send (struct peer *peer, afi_t afi, saf Line 1163  bgp_capability_send (struct peer *peer, afi_t afi, saf
   
   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);    BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
 }  }
 /* RFC1771 6.8 Connection collision detection. */  /* RFC1771 6.8 Connection collision detection. */
 static int  static int
 bgp_collision_detect (struct peer *new, struct in_addr remote_id)  bgp_collision_detect (struct peer *new, struct in_addr remote_id)
Line 1485  bgp_open_receive (struct peer *peer, bgp_size_t size) Line 1553  bgp_open_receive (struct peer *peer, bgp_size_t size)
         {          {
           bgp_notify_send (peer,            bgp_notify_send (peer,
                  BGP_NOTIFY_OPEN_ERR,                   BGP_NOTIFY_OPEN_ERR,
                 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);                 BGP_NOTIFY_OPEN_UNSPECIFIC);
           return ret;            return ret;
         }          }
     }      }
Line 1512  bgp_open_receive (struct peer *peer, bgp_size_t size) Line 1580  bgp_open_receive (struct peer *peer, bgp_size_t size)
   
   /* Get sockname. */    /* Get sockname. */
   bgp_getsockname (peer);    bgp_getsockname (peer);
     peer->rtt = sockopt_tcp_rtt (peer->fd);
   
   BGP_EVENT_ADD (peer, Receive_OPEN_message);    BGP_EVENT_ADD (peer, Receive_OPEN_message);
   
Line 1522  bgp_open_receive (struct peer *peer, bgp_size_t size) Line 1591  bgp_open_receive (struct peer *peer, bgp_size_t size)
   return 0;    return 0;
 }  }
   
   /* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */
   int
   bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
   {
     switch (packet->safi)
       {
         case SAFI_UNICAST:
         case SAFI_MULTICAST:
           return bgp_nlri_parse_ip (peer, attr, packet);
         case SAFI_MPLS_VPN:
         case SAFI_MPLS_LABELED_VPN:
           return bgp_nlri_parse_vpn (peer, attr, packet);
         case SAFI_ENCAP:
           return bgp_nlri_parse_encap (peer, attr, packet);
       }
     return -1;
   }
   
 /* Parse BGP Update packet and make attribute object. */  /* Parse BGP Update packet and make attribute object. */
 static int  static int
 bgp_update_receive (struct peer *peer, bgp_size_t size)  bgp_update_receive (struct peer *peer, bgp_size_t size)
 {  {
  int ret;  int ret, nlri_ret;
   u_char *end;    u_char *end;
   struct stream *s;    struct stream *s;
   struct attr attr;    struct attr attr;
Line 1534  bgp_update_receive (struct peer *peer, bgp_size_t size Line 1621  bgp_update_receive (struct peer *peer, bgp_size_t size
   bgp_size_t attribute_len;    bgp_size_t attribute_len;
   bgp_size_t update_len;    bgp_size_t update_len;
   bgp_size_t withdraw_len;    bgp_size_t withdraw_len;
  struct bgp_nlri update;  int i;
  struct bgp_nlri withdraw;  
  struct bgp_nlri mp_update;  enum NLRI_TYPES {
  struct bgp_nlri mp_withdraw;    NLRI_UPDATE,
     NLRI_WITHDRAW,
     NLRI_MP_UPDATE,
     NLRI_MP_WITHDRAW,
     NLRI_TYPE_MAX,
   };
   struct bgp_nlri nlris[NLRI_TYPE_MAX];
   
   /* Status must be Established. */    /* Status must be Established. */
   if (peer->status != Established)     if (peer->status != Established) 
Line 1551  bgp_update_receive (struct peer *peer, bgp_size_t size Line 1644  bgp_update_receive (struct peer *peer, bgp_size_t size
   /* Set initial values. */    /* Set initial values. */
   memset (&attr, 0, sizeof (struct attr));    memset (&attr, 0, sizeof (struct attr));
   memset (&extra, 0, sizeof (struct attr_extra));    memset (&extra, 0, sizeof (struct attr_extra));
  memset (&update, 0, sizeof (struct bgp_nlri));  memset (&nlris, 0, sizeof nlris);
  memset (&withdraw, 0, sizeof (struct bgp_nlri)); 
  memset (&mp_update, 0, sizeof (struct bgp_nlri)); 
  memset (&mp_withdraw, 0, sizeof (struct bgp_nlri)); 
   attr.extra = &extra;    attr.extra = &extra;
   
   s = peer->ibuf;    s = peer->ibuf;
Line 1591  bgp_update_receive (struct peer *peer, bgp_size_t size Line 1681  bgp_update_receive (struct peer *peer, bgp_size_t size
   /* Unfeasible Route packet format check. */    /* Unfeasible Route packet format check. */
   if (withdraw_len > 0)    if (withdraw_len > 0)
     {      {
      ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);      nlris[NLRI_WITHDRAW].afi = AFI_IP;
      if (ret < 0)      nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
        return -1;      nlris[NLRI_WITHDRAW].nlri = stream_pnt (s);
      nlris[NLRI_WITHDRAW].length = withdraw_len;
       
       if (BGP_DEBUG (packet, PACKET_RECV))        if (BGP_DEBUG (packet, PACKET_RECV))
         zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);          zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
   
       withdraw.afi = AFI_IP;  
       withdraw.safi = SAFI_UNICAST;  
       withdraw.nlri = stream_pnt (s);  
       withdraw.length = withdraw_len;  
       stream_forward_getp (s, withdraw_len);        stream_forward_getp (s, withdraw_len);
     }      }
       
Line 1647  bgp_update_receive (struct peer *peer, bgp_size_t size Line 1734  bgp_update_receive (struct peer *peer, bgp_size_t size
   if (attribute_len)    if (attribute_len)
     {      {
       attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,         attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len, 
                            &mp_update, &mp_withdraw);                            &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]);
       if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)        if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
        return -1;        {
           bgp_attr_unintern_sub (&attr);
           bgp_attr_flush (&attr);
           return -1;
         }
     }      }
       
   /* Logging the attribute. */    /* Logging the attribute. */
Line 1678  bgp_update_receive (struct peer *peer, bgp_size_t size Line 1769  bgp_update_receive (struct peer *peer, bgp_size_t size
   
   if (update_len)    if (update_len)
     {      {
       /* Check NLRI packet format and prefix length. */  
       ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);  
       if (ret < 0)  
         {  
           bgp_attr_unintern_sub (&attr);  
           return -1;  
         }  
   
       /* Set NLRI portion to structure. */        /* Set NLRI portion to structure. */
      update.afi = AFI_IP;      nlris[NLRI_UPDATE].afi = AFI_IP;
      update.safi = SAFI_UNICAST;      nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
      update.nlri = stream_pnt (s);      nlris[NLRI_UPDATE].nlri = stream_pnt (s);
      update.length = update_len;      nlris[NLRI_UPDATE].length = update_len;
       
       stream_forward_getp (s, update_len);        stream_forward_getp (s, update_len);
     }      }
  
  /* NLRI is processed only when the peer is configured specific  /* Parse any given NLRIs */
     Address Family and Subsequent Address Family. */  for (i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++)
  if (peer->afc[AFI_IP][SAFI_UNICAST]) 
     {      {
      if (withdraw.length)      /* We use afi and safi as indices into tables and what not.  It would
        bgp_nlri_parse (peer, NULL, &withdraw);       * be impossible, at this time, to support unknown afi/safis.  And
       * anyway, the peer needs to be configured to enable the afi/safi
      if (update.length)       * explicitly which requires UI support.
        {       *
          /* We check well-known attribute only for IPv4 unicast       * Ignore unknown afi/safi NLRIs.
             update. */       *
          ret = bgp_attr_check (peer, &attr);       * Note: this means nlri[x].afi/safi still can not be trusted for
          if (ret < 0)       * indexing later in this function!
            {       *
              bgp_attr_unintern_sub (&attr);       * Note2: This will also remap the wire code-point for VPN safi to the
              return -1;       * internal safi_t point, as needs be.
            }       */
      if (!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
          bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);        {
        }          plog_info (peer->log,
                     "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
      if (mp_update.length                     peer->host, nlris[i].afi, nlris[i].safi);
          && mp_update.afi == AFI_IP           continue;
          && mp_update.safi == SAFI_UNICAST)        }
        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);      
      /* NLRI is processed only when the peer is configured specific
      if (mp_withdraw.length         Address Family and Subsequent Address Family. */
          && mp_withdraw.afi == AFI_IP       if (!peer->afc[nlris[i].afi][nlris[i].safi])
          && mp_withdraw.safi == SAFI_UNICAST)        {
        bgp_nlri_parse (peer, NULL, &mp_withdraw);          plog_info (peer->log,
                     "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
      if (! attribute_len && ! withdraw_len)                     peer->host, nlris[i].afi, nlris[i].safi);
        {          continue;
          /* End-of-RIB received */        }
          SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],      
                    PEER_STATUS_EOR_RECEIVED);      /* EoR handled later */
      if (nlris[i].length == 0)
          /* NSF delete stale route */        continue;
          if (peer->nsf[AFI_IP][SAFI_UNICAST])      
            bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);      switch (i)
        {
          if (BGP_DEBUG (normal, NORMAL))          case NLRI_UPDATE:
            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",          case NLRI_MP_UPDATE:
                  peer->host);            nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]);
        }            break;
           case NLRI_WITHDRAW:
           case NLRI_MP_WITHDRAW:
             nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]);
         }
       
       if (nlri_ret < 0)
         {
           plog_err (peer->log, 
                     "%s [Error] Error parsing NLRI", peer->host);
           if (peer->status == Established)
             bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
                              i <= NLRI_WITHDRAW 
                                ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
                                : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
           bgp_attr_unintern_sub (&attr);
           return -1;
         }
     }      }
  if (peer->afc[AFI_IP][SAFI_MULTICAST])  
   /* EoR checks.
    *
    * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
    * and MP EoR should have only an empty MP_UNREACH
    */
   if (!update_len && !withdraw_len
       && nlris[NLRI_MP_UPDATE].length == 0)
     {      {
      if (mp_update.length      afi_t afi = 0;
          && mp_update.afi == AFI_IP       safi_t safi;
          && mp_update.safi == SAFI_MULTICAST)      
        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);      /* Non-MP IPv4/Unicast is a completely empty UPDATE - already
       * checked update and withdraw NLRI lengths are 0.
      if (mp_withdraw.length       */ 
          && mp_withdraw.afi == AFI_IP       if (!attribute_len)
          && mp_withdraw.safi == SAFI_MULTICAST)        {
        bgp_nlri_parse (peer, NULL, &mp_withdraw);          afi = AFI_IP;
          safi = SAFI_UNICAST;
      if (! withdraw_len        }
          && mp_withdraw.afi == AFI_IP      /* otherwise MP AFI/SAFI is an empty update, other than an empty
          && mp_withdraw.safi == SAFI_MULTICAST       * MP_UNREACH_NLRI attr (with an AFI/SAFI we recognise).
          && mp_withdraw.length == 0)       */
        {      else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
                && nlris[NLRI_MP_WITHDRAW].length == 0
                && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
                                               &nlris[NLRI_MP_WITHDRAW].safi))
         {
           afi = nlris[NLRI_MP_WITHDRAW].afi;
           safi = nlris[NLRI_MP_WITHDRAW].safi;
         }
       
       if (afi && peer->afc[afi][safi])
         {
           /* End-of-RIB received */            /* End-of-RIB received */
          SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],          SET_FLAG (peer->af_sflags[afi][safi],
                     PEER_STATUS_EOR_RECEIVED);                      PEER_STATUS_EOR_RECEIVED);
   
           /* NSF delete stale route */            /* NSF delete stale route */
          if (peer->nsf[AFI_IP][SAFI_MULTICAST])          if (peer->nsf[afi][safi])
            bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);            bgp_clear_stale_route (peer, afi, safi);
   
           if (BGP_DEBUG (normal, NORMAL))            if (BGP_DEBUG (normal, NORMAL))
            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for %s from %s",
                  peer->host);                  peer->host, afi_safi_print (afi, safi));
        }        }
     }      }
  if (peer->afc[AFI_IP6][SAFI_UNICAST])  
    { 
      if (mp_update.length  
          && mp_update.afi == AFI_IP6  
          && mp_update.safi == SAFI_UNICAST) 
        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update); 
 
      if (mp_withdraw.length  
          && mp_withdraw.afi == AFI_IP6  
          && mp_withdraw.safi == SAFI_UNICAST) 
        bgp_nlri_parse (peer, NULL, &mp_withdraw); 
 
      if (! withdraw_len 
          && mp_withdraw.afi == AFI_IP6 
          && mp_withdraw.safi == SAFI_UNICAST 
          && mp_withdraw.length == 0) 
        { 
          /* End-of-RIB received */ 
          SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED); 
 
          /* NSF delete stale route */ 
          if (peer->nsf[AFI_IP6][SAFI_UNICAST]) 
            bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST); 
 
          if (BGP_DEBUG (normal, NORMAL)) 
            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s", 
                  peer->host); 
        } 
    } 
  if (peer->afc[AFI_IP6][SAFI_MULTICAST]) 
    { 
      if (mp_update.length  
          && mp_update.afi == AFI_IP6  
          && mp_update.safi == SAFI_MULTICAST) 
        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update); 
 
      if (mp_withdraw.length  
          && mp_withdraw.afi == AFI_IP6  
          && mp_withdraw.safi == SAFI_MULTICAST) 
        bgp_nlri_parse (peer, NULL, &mp_withdraw); 
 
      if (! withdraw_len 
          && mp_withdraw.afi == AFI_IP6 
          && mp_withdraw.safi == SAFI_MULTICAST 
          && mp_withdraw.length == 0) 
        { 
          /* End-of-RIB received */ 
 
          /* NSF delete stale route */ 
          if (peer->nsf[AFI_IP6][SAFI_MULTICAST]) 
            bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST); 
 
          if (BGP_DEBUG (update, UPDATE_IN)) 
            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s", 
                  peer->host); 
        } 
    } 
  if (peer->afc[AFI_IP][SAFI_MPLS_VPN]) 
    { 
      if (mp_update.length  
          && mp_update.afi == AFI_IP  
          && mp_update.safi == SAFI_MPLS_LABELED_VPN) 
        bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update); 
 
      if (mp_withdraw.length  
          && mp_withdraw.afi == AFI_IP  
          && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN) 
        bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw); 
 
      if (! withdraw_len 
          && mp_withdraw.afi == AFI_IP 
          && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN 
          && mp_withdraw.length == 0) 
        { 
          /* End-of-RIB received */ 
 
          if (BGP_DEBUG (update, UPDATE_IN)) 
            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s", 
                  peer->host); 
        } 
    } 
 
   /* Everything is done.  We unintern temporary structures which    /* Everything is done.  We unintern temporary structures which
      interned in bgp_attr_parse(). */       interned in bgp_attr_parse(). */
   bgp_attr_unintern_sub (&attr);    bgp_attr_unintern_sub (&attr);
     bgp_attr_flush (&attr);
   
   /* If peering is stopped due to some reason, do not generate BGP    /* If peering is stopped due to some reason, do not generate BGP
      event.  */       event.  */
Line 1926  bgp_notify_receive (struct peer *peer, bgp_size_t size Line 1963  bgp_notify_receive (struct peer *peer, bgp_size_t size
   
     bgp_notify_print(peer, &bgp_notify, "received");      bgp_notify_print(peer, &bgp_notify, "received");
     if (bgp_notify.data)      if (bgp_notify.data)
      XFREE (MTYPE_TMP, bgp_notify.data);      {
         XFREE (MTYPE_TMP, bgp_notify.data);
         bgp_notify.data = NULL;
         bgp_notify.length = 0;
       }
   }    }
   
   /* peer count update */    /* peer count update */
Line 1962  bgp_route_refresh_receive (struct peer *peer, bgp_size Line 2003  bgp_route_refresh_receive (struct peer *peer, bgp_size
 {  {
   afi_t afi;    afi_t afi;
   safi_t safi;    safi_t safi;
   u_char reserved;  
   struct stream *s;    struct stream *s;
   
   /* If peer does not have the capability, send notification. */    /* If peer does not have the capability, send notification. */
Line 1990  bgp_route_refresh_receive (struct peer *peer, bgp_size Line 2030  bgp_route_refresh_receive (struct peer *peer, bgp_size
       
   /* Parse packet. */    /* Parse packet. */
   afi = stream_getw (s);    afi = stream_getw (s);
  reserved = stream_getc (s);  /* reserved byte */
   stream_getc (s);
   safi = stream_getc (s);    safi = stream_getc (s);
   
   if (BGP_DEBUG (normal, NORMAL))    if (BGP_DEBUG (normal, NORMAL))
Line 2042  bgp_route_refresh_receive (struct peer *peer, bgp_size Line 2083  bgp_route_refresh_receive (struct peer *peer, bgp_size
           if (orf_type == ORF_TYPE_PREFIX            if (orf_type == ORF_TYPE_PREFIX
               || orf_type == ORF_TYPE_PREFIX_OLD)                || orf_type == ORF_TYPE_PREFIX_OLD)
             {              {
              u_char *p_pnt = stream_pnt (s);              uint8_t *p_pnt = stream_pnt (s);
              u_char *p_end = stream_pnt (s) + orf_len;              uint8_t *p_end = stream_pnt (s) + orf_len;
               struct orf_prefix orfp;                struct orf_prefix orfp;
               u_char common = 0;                u_char common = 0;
               u_int32_t seq;                u_int32_t seq;
Line 2080  bgp_route_refresh_receive (struct peer *peer, bgp_size Line 2121  bgp_route_refresh_receive (struct peer *peer, bgp_size
                     {                      {
                       if (BGP_DEBUG (normal, NORMAL))                        if (BGP_DEBUG (normal, NORMAL))
                         zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);                          zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
                      prefix_bgp_orf_remove_all (name);                      prefix_bgp_orf_remove_all (afi, name);
                       break;                        break;
                     }                      }
                  ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;                  ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
                   if (ok)                    if (ok)
                     {                      {
                       memcpy (&seq, p_pnt, sizeof (u_int32_t));                        memcpy (&seq, p_pnt, sizeof (u_int32_t));
Line 2135  bgp_route_refresh_receive (struct peer *peer, bgp_size Line 2176  bgp_route_refresh_receive (struct peer *peer, bgp_size
                     ret = prefix_bgp_orf_set (name, afi, &orfp,                      ret = prefix_bgp_orf_set (name, afi, &orfp,
                                    (common & ORF_COMMON_PART_DENY ? 0 : 1 ),                                     (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
                                    (common & ORF_COMMON_PART_REMOVE ? 0 : 1));                                     (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
                  
                  if (!ok || (ret != CMD_SUCCESS))                  if (!ok || (ok && ret != CMD_SUCCESS))
                     {                      {
                       if (BGP_DEBUG (normal, NORMAL))                        if (BGP_DEBUG (normal, NORMAL))
                         zlog_debug ("%s Received misformatted prefixlist ORF."                          zlog_debug ("%s Received misformatted prefixlist ORF."
                                     " Remove All pfxlist", peer->host);                                      " Remove All pfxlist", peer->host);
                      prefix_bgp_orf_remove_all (name);                      prefix_bgp_orf_remove_all (afi, name);
                       break;                        break;
                     }                      }
                 }                  }
               peer->orf_plist[afi][safi] =                peer->orf_plist[afi][safi] =
                         prefix_list_lookup (AFI_ORF_PREFIX, name);                         prefix_bgp_orf_lookup (afi, name);
             }              }
           stream_forward_getp (s, orf_len);            stream_forward_getp (s, orf_len);
         }          }
Line 2172  bgp_capability_msg_parse (struct peer *peer, u_char *p Line 2213  bgp_capability_msg_parse (struct peer *peer, u_char *p
   struct capability_mp_data mpc;    struct capability_mp_data mpc;
   struct capability_header *hdr;    struct capability_header *hdr;
   u_char action;    u_char action;
   struct bgp *bgp;  
   afi_t afi;    afi_t afi;
   safi_t safi;    safi_t safi;
   
   bgp = peer->bgp;  
   end = pnt + length;    end = pnt + length;
   
   while (pnt < end)    while (pnt < end)
Line 2310  bgp_capability_receive (struct peer *peer, bgp_size_t  Line 2349  bgp_capability_receive (struct peer *peer, bgp_size_t 
   /* Parse packet. */    /* Parse packet. */
   return bgp_capability_msg_parse (peer, pnt, size);    return bgp_capability_msg_parse (peer, pnt, size);
 }  }
 /* BGP read utility function. */  /* BGP read utility function. */
 static int  static int
 bgp_read_packet (struct peer *peer)  bgp_read_packet (struct peer *peer)

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


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