Diff for /embedaddon/quagga/bgpd/bgp_open.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 27  Software Foundation, Inc., 59 Temple Place - Suite 330 Line 27  Software Foundation, Inc., 59 Temple Place - Suite 330
 #include "log.h"  #include "log.h"
 #include "command.h"  #include "command.h"
 #include "memory.h"  #include "memory.h"
   #include "filter.h"
   
 #include "bgpd/bgpd.h"  #include "bgpd/bgpd.h"
 #include "bgpd/bgp_attr.h"  #include "bgpd/bgp_attr.h"
Line 96  bgp_capability_vty_out (struct vty *vty, struct peer * Line 97  bgp_capability_vty_out (struct vty *vty, struct peer *
             case SAFI_MPLS_LABELED_VPN:              case SAFI_MPLS_LABELED_VPN:
               vty_out (vty, "SAFI MPLS-labeled VPN");                vty_out (vty, "SAFI MPLS-labeled VPN");
               break;                break;
               case SAFI_ENCAP:
                 vty_out (vty, "SAFI ENCAP");
                 break;
             default:              default:
               vty_out (vty, "SAFI Unknown %d ", mpc.safi);                vty_out (vty, "SAFI Unknown %d ", mpc.safi);
               break;                break;
Line 126  bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi) Line 130  bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
 {  {
   switch (afi)    switch (afi)
     {      {
      case AFI_IP:    case AFI_IP:
#ifdef HAVE_IPV6    case AFI_IP6:
      case AFI_IP6:      switch (*safi)
#endif        {
        switch (*safi)          /* BGP MPLS-labeled VPN SAFI isn't contigious with others, remap */
          {        case SAFI_MPLS_LABELED_VPN:
            /* BGP MPLS-labeled VPN SAFI isn't contigious with others, remap */          *safi = SAFI_MPLS_VPN;
            case SAFI_MPLS_LABELED_VPN:        case SAFI_UNICAST:
              *safi = SAFI_MPLS_VPN;        case SAFI_MULTICAST:
            case SAFI_UNICAST:        case SAFI_MPLS_VPN:
            case SAFI_MULTICAST:        case SAFI_ENCAP:
            case SAFI_MPLS_VPN:          return 1;
              return 1;        }
          }      break;
     }      }
   
   zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);    zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
  
   return 0;    return 0;
 }  }
   
Line 230  bgp_capability_orf_entry (struct peer *peer, struct ca Line 235  bgp_capability_orf_entry (struct peer *peer, struct ca
     }      }
       
   /* validate number field */    /* validate number field */
  if (sizeof (struct capability_orf_entry) + (entry.num * 2) > hdr->length)  if (CAPABILITY_CODE_ORF_LEN + (entry.num * 2) > hdr->length)
     {      {
       zlog_info ("%s ORF Capability entry length error,"        zlog_info ("%s ORF Capability entry length error,"
                  " Cap length %u, num %u",                   " Cap length %u, num %u",
                  peer->host, hdr->length, entry.num);                   peer->host, hdr->length, entry.num);
      bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);      bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSPECIFIC);
       return -1;        return -1;
     }      }
   
Line 338  bgp_capability_restart (struct peer *peer, struct capa Line 343  bgp_capability_restart (struct peer *peer, struct capa
 {  {
   struct stream *s = BGP_INPUT (peer);    struct stream *s = BGP_INPUT (peer);
   u_int16_t restart_flag_time;    u_int16_t restart_flag_time;
   int restart_bit = 0;  
   size_t end = stream_get_getp (s) + caphdr->length;    size_t end = stream_get_getp (s) + caphdr->length;
   
   SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);    SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
   restart_flag_time = stream_getw(s);    restart_flag_time = stream_getw(s);
   if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))    if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
    restart_bit = 1;    SET_FLAG (peer->cap, PEER_CAP_RESTART_BIT_RCV);
   
   UNSET_FLAG (restart_flag_time, 0xF000);    UNSET_FLAG (restart_flag_time, 0xF000);
   peer->v_gr_restart = restart_flag_time;    peer->v_gr_restart = restart_flag_time;
   
Line 352  bgp_capability_restart (struct peer *peer, struct capa Line 357  bgp_capability_restart (struct peer *peer, struct capa
     {      {
       zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);        zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
       zlog_debug ("%s Peer has%srestarted. Restart Time : %d",        zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
                  peer->host, restart_bit ? " " : " not ",                  peer->host,
                   CHECK_FLAG (peer->cap, PEER_CAP_RESTART_BIT_RCV) ? " " 
                                                                    : " not ",
                   peer->v_gr_restart);                    peer->v_gr_restart);
     }      }
   
Line 430  static const int capcode_str_max = array_size(capcode_ Line 437  static const int capcode_str_max = array_size(capcode_
 /* Minimum sizes for length field of each cap (so not inc. the header) */  /* Minimum sizes for length field of each cap (so not inc. the header) */
 static const size_t cap_minsizes[] =   static const size_t cap_minsizes[] = 
 {  {
  [CAPABILITY_CODE_MP]          = sizeof (struct capability_mp_data),  [CAPABILITY_CODE_MP]          = CAPABILITY_CODE_MP_LEN,
   [CAPABILITY_CODE_REFRESH]     = CAPABILITY_CODE_REFRESH_LEN,    [CAPABILITY_CODE_REFRESH]     = CAPABILITY_CODE_REFRESH_LEN,
  [CAPABILITY_CODE_ORF]         = sizeof (struct capability_orf_entry),  [CAPABILITY_CODE_ORF]         = CAPABILITY_CODE_ORF_LEN,
  [CAPABILITY_CODE_RESTART]     = sizeof (struct capability_gr),  [CAPABILITY_CODE_RESTART]     = CAPABILITY_CODE_RESTART_LEN,
   [CAPABILITY_CODE_AS4]         = CAPABILITY_CODE_AS4_LEN,    [CAPABILITY_CODE_AS4]         = CAPABILITY_CODE_AS4_LEN,
   [CAPABILITY_CODE_DYNAMIC]     = CAPABILITY_CODE_DYNAMIC_LEN,    [CAPABILITY_CODE_DYNAMIC]     = CAPABILITY_CODE_DYNAMIC_LEN,
   [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,    [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
  [CAPABILITY_CODE_ORF_OLD]     = sizeof (struct capability_orf_entry),  [CAPABILITY_CODE_ORF_OLD]     = CAPABILITY_CODE_ORF_LEN,
 };  };
   
   /* value the capability must be a multiple of.
    * 0-data capabilities won't be checked against this.
    * Other capabilities whose data doesn't fall on convenient boundaries for this
    * table should be set to 1.
    */
   static const size_t cap_modsizes[] =
   {
     [CAPABILITY_CODE_MP]          = 4,
     [CAPABILITY_CODE_REFRESH]     = 1,
     [CAPABILITY_CODE_ORF]         = 1,
     [CAPABILITY_CODE_RESTART]     = 1,
     [CAPABILITY_CODE_AS4]         = 4,
     [CAPABILITY_CODE_DYNAMIC]     = 1,
     [CAPABILITY_CODE_REFRESH_OLD] = 1,
     [CAPABILITY_CODE_ORF_OLD]     = 1,
   };
   
 /**  /**
  * Parse given capability.   * Parse given capability.
  * XXX: This is reading into a stream, but not using stream API   * XXX: This is reading into a stream, but not using stream API
Line 467  bgp_capability_parse (struct peer *peer, size_t length Line 491  bgp_capability_parse (struct peer *peer, size_t length
       if (stream_get_getp(s) + 2 > end)        if (stream_get_getp(s) + 2 > end)
         {          {
           zlog_info ("%s Capability length error (< header)", peer->host);            zlog_info ("%s Capability length error (< header)", peer->host);
          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);          bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSPECIFIC);
           return -1;            return -1;
         }          }
               
Line 479  bgp_capability_parse (struct peer *peer, size_t length Line 503  bgp_capability_parse (struct peer *peer, size_t length
       if (start + caphdr.length > end)        if (start + caphdr.length > end)
         {          {
           zlog_info ("%s Capability length error (< length)", peer->host);            zlog_info ("%s Capability length error (< length)", peer->host);
          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);          bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_UNSPECIFIC);
           return -1;            return -1;
         }          }
               
Line 509  bgp_capability_parse (struct peer *peer, size_t length Line 533  bgp_capability_parse (struct peer *peer, size_t length
                              LOOKUP (capcode_str, caphdr.code),                               LOOKUP (capcode_str, caphdr.code),
                              caphdr.length,                                caphdr.length, 
                              (unsigned) cap_minsizes[caphdr.code]);                               (unsigned) cap_minsizes[caphdr.code]);
                  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);                  bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
                                   BGP_NOTIFY_OPEN_UNSPECIFIC);
                   return -1;                    return -1;
                 }                  }
                 if (caphdr.length
                     && caphdr.length % cap_modsizes[caphdr.code] != 0)
                   {
                     zlog_info ("%s %s Capability length error: got %u,"
                                " expected a multiple of %u",
                                peer->host,
                                LOOKUP (capcode_str, caphdr.code),
                                caphdr.length,
                                (unsigned) cap_modsizes[caphdr.code]);
                     bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
                                            BGP_NOTIFY_OPEN_UNSPECIFIC);
                     return -1;
                   }
           /* we deliberately ignore unknown codes, see below */            /* we deliberately ignore unknown codes, see below */
           default:            default:
             break;              break;
Line 725  bgp_open_option_parse (struct peer *peer, u_char lengt Line 763  bgp_open_option_parse (struct peer *peer, u_char lengt
       if (STREAM_READABLE(s) < 2)        if (STREAM_READABLE(s) < 2)
         {          {
           zlog_info ("%s Option length error", peer->host);            zlog_info ("%s Option length error", peer->host);
          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);          bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
                                  BGP_NOTIFY_OPEN_UNSPECIFIC);
           return -1;            return -1;
         }          }
   
Line 737  bgp_open_option_parse (struct peer *peer, u_char lengt Line 776  bgp_open_option_parse (struct peer *peer, u_char lengt
       if (STREAM_READABLE (s) < opt_length)        if (STREAM_READABLE (s) < opt_length)
         {          {
           zlog_info ("%s Option length error", peer->host);            zlog_info ("%s Option length error", peer->host);
          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);          bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
                                  BGP_NOTIFY_OPEN_UNSPECIFIC);
           return -1;            return -1;
         }          }
   
Line 805  bgp_open_option_parse (struct peer *peer, u_char lengt Line 845  bgp_open_option_parse (struct peer *peer, u_char lengt
       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])
         {          {
           plog_err (peer->log, "%s [Error] Configured AFI/SAFIs do not "            plog_err (peer->log, "%s [Error] Configured AFI/SAFIs do not "
                     "overlap with received MP capabilities",                      "overlap with received MP capabilities",
Line 898  void Line 941  void
 bgp_open_capability (struct stream *s, struct peer *peer)  bgp_open_capability (struct stream *s, struct peer *peer)
 {  {
   u_char len;    u_char len;
  unsigned long cp;  unsigned long cp, capp, rcapp;
   afi_t afi;    afi_t afi;
   safi_t safi;    safi_t safi;
   as_t local_as;    as_t local_as;
     u_int32_t restart_time;
   
   /* Remember current pointer for Opt Parm Len. */    /* Remember current pointer for Opt Parm Len. */
   cp = stream_get_endp (s);    cp = stream_get_endp (s);
Line 950  bgp_open_capability (struct stream *s, struct peer *pe Line 994  bgp_open_capability (struct stream *s, struct peer *pe
       stream_putc (s, 0);        stream_putc (s, 0);
       stream_putc (s, SAFI_MPLS_LABELED_VPN);        stream_putc (s, SAFI_MPLS_LABELED_VPN);
     }      }
#ifdef HAVE_IPV6  /* ENCAP */
   if (peer->afc[AFI_IP][SAFI_ENCAP])
     {
       peer->afc_adv[AFI_IP][SAFI_ENCAP] = 1;
       stream_putc (s, BGP_OPEN_OPT_CAP);
       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
       stream_putc (s, CAPABILITY_CODE_MP);
       stream_putc (s, CAPABILITY_CODE_MP_LEN);
       stream_putw (s, AFI_IP);
       stream_putc (s, 0);
       stream_putc (s, SAFI_ENCAP);
     }
   /* IPv6 unicast. */    /* IPv6 unicast. */
   if (peer->afc[AFI_IP6][SAFI_UNICAST])    if (peer->afc[AFI_IP6][SAFI_UNICAST])
     {      {
Line 975  bgp_open_capability (struct stream *s, struct peer *pe Line 1030  bgp_open_capability (struct stream *s, struct peer *pe
       stream_putc (s, 0);        stream_putc (s, 0);
       stream_putc (s, SAFI_MULTICAST);        stream_putc (s, SAFI_MULTICAST);
     }      }
#endif /* HAVE_IPV6 */  /* IPv6 VPN. */
   if (peer->afc[AFI_IP6][SAFI_MPLS_VPN])
     {
       peer->afc_adv[AFI_IP6][SAFI_MPLS_VPN] = 1;
       stream_putc (s, BGP_OPEN_OPT_CAP);
       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
       stream_putc (s, CAPABILITY_CODE_MP);
       stream_putc (s, CAPABILITY_CODE_MP_LEN);
       stream_putw (s, AFI_IP6);
       stream_putc (s, 0);
       stream_putc (s, SAFI_MPLS_LABELED_VPN);
     }
   /* IPv6 ENCAP. */
   if (peer->afc[AFI_IP6][SAFI_ENCAP])
     {
       peer->afc_adv[AFI_IP6][SAFI_ENCAP] = 1;
       stream_putc (s, BGP_OPEN_OPT_CAP);
       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
       stream_putc (s, CAPABILITY_CODE_MP);
       stream_putc (s, CAPABILITY_CODE_MP_LEN);
       stream_putw (s, AFI_IP6);
       stream_putc (s, 0);
       stream_putc (s, SAFI_ENCAP);
     }
   
   /* Route refresh. */    /* Route refresh. */
   SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);    SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
Line 1020  bgp_open_capability (struct stream *s, struct peer *pe Line 1098  bgp_open_capability (struct stream *s, struct peer *pe
       stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);        stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
     }      }
   
  /* Graceful restart capability */  /* Sending base graceful-restart capability irrespective of the config */
   SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
   stream_putc (s, BGP_OPEN_OPT_CAP);
   capp = stream_get_endp (s);           /* Set Capability Len Pointer */
   stream_putc (s, 0);                   /* Capability Length */
   stream_putc (s, CAPABILITY_CODE_RESTART);
   rcapp = stream_get_endp (s);          /* Set Restart Capability Len Pointer */
   stream_putc (s, 0);
   restart_time = peer->bgp->restart_time;
   if (peer->bgp->t_startup)
     {
       SET_FLAG (restart_time, RESTART_R_BIT);
       SET_FLAG (peer->cap, PEER_CAP_RESTART_BIT_ADV);
     }
   stream_putw (s, restart_time);
 
   /* Send address-family specific graceful-restart capability only when GR config
      is present */
   if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))    if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
     {      {
      SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);      for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
      stream_putc (s, BGP_OPEN_OPT_CAP);        for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
      stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);          if (peer->afc[afi][safi])
      stream_putc (s, CAPABILITY_CODE_RESTART);            {
      stream_putc (s, CAPABILITY_CODE_RESTART_LEN);              stream_putw (s, afi);
      stream_putw (s, peer->bgp->restart_time);              stream_putc (s, safi);
     }              stream_putc (s, 0); //Forwarding is not retained as of now.
             }
     }
 
   /* Total Graceful restart capability Len. */
   len = stream_get_endp (s) - rcapp - 1;
   stream_putc_at (s, rcapp, len);
 
   /* Total Capability Len. */
   len = stream_get_endp (s) - capp - 1;
   stream_putc_at (s, capp, len);
   
   /* Total Opt Parm Len. */    /* Total Opt Parm Len. */
   len = stream_get_endp (s) - cp - 1;    len = stream_get_endp (s) - cp - 1;

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


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