Annotation of embedaddon/quagga/bgpd/bgp_open.c, revision 1.1.1.1

1.1       misho       1: /* BGP open message handling
                      2:    Copyright (C) 1998, 1999 Kunihiro Ishiguro
                      3: 
                      4: This file is part of GNU Zebra.
                      5: 
                      6: GNU Zebra is free software; you can redistribute it and/or modify it
                      7: under the terms of the GNU General Public License as published by the
                      8: Free Software Foundation; either version 2, or (at your option) any
                      9: later version.
                     10: 
                     11: GNU Zebra is distributed in the hope that it will be useful, but
                     12: WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14: General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU Zebra; see the file COPYING.  If not, write to the Free
                     18: Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     19: 02111-1307, USA.  */
                     20: 
                     21: #include <zebra.h>
                     22: 
                     23: #include "linklist.h"
                     24: #include "prefix.h"
                     25: #include "stream.h"
                     26: #include "thread.h"
                     27: #include "log.h"
                     28: #include "command.h"
                     29: #include "memory.h"
                     30: 
                     31: #include "bgpd/bgpd.h"
                     32: #include "bgpd/bgp_attr.h"
                     33: #include "bgpd/bgp_debug.h"
                     34: #include "bgpd/bgp_fsm.h"
                     35: #include "bgpd/bgp_packet.h"
                     36: #include "bgpd/bgp_open.h"
                     37: #include "bgpd/bgp_aspath.h"
                     38: #include "bgpd/bgp_vty.h"
                     39: 
                     40: /* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
                     41:    negotiate remote peer supports extentions or not. But if
                     42:    remote-peer doesn't supports negotiation process itself.  We would
                     43:    like to do manual configuration.
                     44: 
                     45:    So there is many configurable point.  First of all we want set each
                     46:    peer whether we send capability negotiation to the peer or not.
                     47:    Next, if we send capability to the peer we want to set my capabilty
                     48:    inforation at each peer. */
                     49: 
                     50: void
                     51: bgp_capability_vty_out (struct vty *vty, struct peer *peer)
                     52: {
                     53:   char *pnt;
                     54:   char *end;
                     55:   struct capability_mp_data mpc;
                     56:   struct capability_header *hdr;
                     57: 
                     58:   pnt = peer->notify.data;
                     59:   end = pnt + peer->notify.length;
                     60:   
                     61:   while (pnt < end)
                     62:     {
                     63:       if (pnt + sizeof (struct capability_mp_data) + 2 > end)
                     64:        return;
                     65:       
                     66:       hdr = (struct capability_header *)pnt;
                     67:       if (pnt + hdr->length + 2 > end)
                     68:        return;
                     69: 
                     70:       memcpy (&mpc, pnt + 2, sizeof(struct capability_mp_data));
                     71: 
                     72:       if (hdr->code == CAPABILITY_CODE_MP)
                     73:        {
                     74:          vty_out (vty, "  Capability error for: Multi protocol ");
                     75: 
                     76:          switch (ntohs (mpc.afi))
                     77:            {
                     78:            case AFI_IP:
                     79:              vty_out (vty, "AFI IPv4, ");
                     80:              break;
                     81:            case AFI_IP6:
                     82:              vty_out (vty, "AFI IPv6, ");
                     83:              break;
                     84:            default:
                     85:              vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
                     86:              break;
                     87:            }
                     88:          switch (mpc.safi)
                     89:            {
                     90:            case SAFI_UNICAST:
                     91:              vty_out (vty, "SAFI Unicast");
                     92:              break;
                     93:            case SAFI_MULTICAST:
                     94:              vty_out (vty, "SAFI Multicast");
                     95:              break;
                     96:            case SAFI_UNICAST_MULTICAST:
                     97:              vty_out (vty, "SAFI Unicast Multicast");
                     98:              break;
                     99:            case BGP_SAFI_VPNV4:
                    100:              vty_out (vty, "SAFI MPLS-VPN");
                    101:              break;
                    102:            default:
                    103:              vty_out (vty, "SAFI Unknown %d ", mpc.safi);
                    104:              break;
                    105:            }
                    106:          vty_out (vty, "%s", VTY_NEWLINE);
                    107:        }
                    108:       else if (hdr->code >= 128)
                    109:        vty_out (vty, "  Capability error: vendor specific capability code %d",
                    110:                 hdr->code);
                    111:       else
                    112:        vty_out (vty, "  Capability error: unknown capability code %d", 
                    113:                 hdr->code);
                    114: 
                    115:       pnt += hdr->length + 2;
                    116:     }
                    117: }
                    118: 
                    119: static void 
                    120: bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
                    121: {
                    122:   mpc->afi = stream_getw (s);
                    123:   mpc->reserved = stream_getc (s);
                    124:   mpc->safi = stream_getc (s);
                    125: }
                    126: 
                    127: int
                    128: bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
                    129: {
                    130:   /* VPNvX are AFI specific */
                    131:   if ((afi == AFI_IP6 && *safi == BGP_SAFI_VPNV4)
                    132:       || (afi == AFI_IP && *safi == BGP_SAFI_VPNV6))
                    133:     {
                    134:       zlog_warn ("Invalid afi/safi combination (%u/%u)", afi, *safi);
                    135:       return 0;
                    136:     }
                    137:   
                    138:   switch (afi)
                    139:     {
                    140:       case AFI_IP:
                    141: #ifdef HAVE_IPV6
                    142:       case AFI_IP6:
                    143: #endif
                    144:         switch (*safi)
                    145:           {
                    146:             /* BGP VPNvX SAFI isn't contigious with others, remap */
                    147:             case BGP_SAFI_VPNV4:
                    148:             case BGP_SAFI_VPNV6:
                    149:               *safi = SAFI_MPLS_VPN;
                    150:             case SAFI_UNICAST:
                    151:             case SAFI_MULTICAST:
                    152:             case SAFI_MPLS_VPN:
                    153:               return 1;
                    154:           }
                    155:     }
                    156:   zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
                    157:   
                    158:   return 0;
                    159: }
                    160: 
                    161: /* Set negotiated capability value. */
                    162: static int
                    163: bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
                    164: {
                    165:   struct capability_mp_data mpc;
                    166:   struct stream *s = BGP_INPUT (peer);
                    167:   
                    168:   bgp_capability_mp_data (s, &mpc);
                    169:   
                    170:   if (BGP_DEBUG (normal, NORMAL))
                    171:     zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
                    172:                peer->host, mpc.afi, mpc.safi);
                    173:   
                    174:   if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi))
                    175:     return -1;
                    176:    
                    177:   /* Now safi remapped, and afi/safi are valid array indices */
                    178:   peer->afc_recv[mpc.afi][mpc.safi] = 1;
                    179:   
                    180:   if (peer->afc[mpc.afi][mpc.safi])
                    181:     peer->afc_nego[mpc.afi][mpc.safi] = 1;
                    182:   else 
                    183:     return -1;
                    184: 
                    185:   return 0;
                    186: }
                    187: 
                    188: static void
                    189: bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
                    190:                                u_char type, u_char mode)
                    191: {
                    192:   if (BGP_DEBUG (normal, NORMAL))
                    193:     zlog_debug ("%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
                    194:               peer->host, afi, safi, type, mode);
                    195: }
                    196: 
                    197: static const struct message orf_type_str[] =
                    198: {
                    199:   { ORF_TYPE_PREFIX,           "Prefixlist"            },
                    200:   { ORF_TYPE_PREFIX_OLD,       "Prefixlist (old)"      },
                    201: };
                    202: static const int orf_type_str_max
                    203:        = sizeof(orf_type_str)/sizeof(orf_type_str[0]);
                    204: 
                    205: static const struct message orf_mode_str[] =
                    206: {
                    207:   { ORF_MODE_RECEIVE,  "Receive"       },
                    208:   { ORF_MODE_SEND,     "Send"          },
                    209:   { ORF_MODE_BOTH,     "Both"          },
                    210: };
                    211: static const int orf_mode_str_max
                    212:         = sizeof(orf_mode_str)/sizeof(orf_mode_str[0]);
                    213: 
                    214: static int
                    215: bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
                    216: {
                    217:   struct stream *s = BGP_INPUT (peer);
                    218:   struct capability_orf_entry entry;
                    219:   afi_t afi;
                    220:   safi_t safi;
                    221:   u_char type;
                    222:   u_char mode;
                    223:   u_int16_t sm_cap = 0; /* capability send-mode receive */
                    224:   u_int16_t rm_cap = 0; /* capability receive-mode receive */ 
                    225:   int i;
                    226: 
                    227:   /* ORF Entry header */
                    228:   bgp_capability_mp_data (s, &entry.mpc);
                    229:   entry.num = stream_getc (s);
                    230:   afi = entry.mpc.afi;
                    231:   safi = entry.mpc.safi;
                    232:   
                    233:   if (BGP_DEBUG (normal, NORMAL))
                    234:     zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u",
                    235:                peer->host, entry.mpc.afi, entry.mpc.safi);
                    236: 
                    237:   /* Check AFI and SAFI. */
                    238:   if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi))
                    239:     {
                    240:       zlog_info ("%s Addr-family %d/%d not supported."
                    241:                  " Ignoring the ORF capability",
                    242:                  peer->host, entry.mpc.afi, entry.mpc.safi);
                    243:       return 0;
                    244:     }
                    245:   
                    246:   /* validate number field */
                    247:   if (sizeof (struct capability_orf_entry) + (entry.num * 2) > hdr->length)
                    248:     {
                    249:       zlog_info ("%s ORF Capability entry length error,"
                    250:                  " Cap length %u, num %u",
                    251:                  peer->host, hdr->length, entry.num);
                    252:       bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    253:       return -1;
                    254:     }
                    255: 
                    256:   for (i = 0 ; i < entry.num ; i++)
                    257:     {
                    258:       type = stream_getc(s);
                    259:       mode = stream_getc(s);
                    260:       
                    261:       /* ORF Mode error check */
                    262:       switch (mode)
                    263:         {
                    264:           case ORF_MODE_BOTH:
                    265:           case ORF_MODE_SEND:
                    266:           case ORF_MODE_RECEIVE:
                    267:             break;
                    268:           default:
                    269:            bgp_capability_orf_not_support (peer, afi, safi, type, mode);
                    270:            continue;
                    271:        }
                    272:       /* ORF Type and afi/safi error checks */
                    273:       /* capcode versus type */
                    274:       switch (hdr->code)
                    275:         {
                    276:           case CAPABILITY_CODE_ORF:
                    277:             switch (type)
                    278:               {
                    279:                 case ORF_TYPE_PREFIX:
                    280:                   break;
                    281:                 default:
                    282:                   bgp_capability_orf_not_support (peer, afi, safi, type, mode);
                    283:                   continue;
                    284:               }
                    285:             break;
                    286:           case CAPABILITY_CODE_ORF_OLD:
                    287:             switch (type)
                    288:               {
                    289:                 case ORF_TYPE_PREFIX_OLD:
                    290:                   break;
                    291:                 default:
                    292:                   bgp_capability_orf_not_support (peer, afi, safi, type, mode);
                    293:                   continue;
                    294:               }
                    295:             break;
                    296:           default:
                    297:             bgp_capability_orf_not_support (peer, afi, safi, type, mode);
                    298:             continue;
                    299:         }
                    300:                 
                    301:       /* AFI vs SAFI */
                    302:       if (!((afi == AFI_IP && safi == SAFI_UNICAST)
                    303:             || (afi == AFI_IP && safi == SAFI_MULTICAST)
                    304:             || (afi == AFI_IP6 && safi == SAFI_UNICAST)))
                    305:         {
                    306:           bgp_capability_orf_not_support (peer, afi, safi, type, mode);
                    307:           continue;
                    308:         }
                    309:       
                    310:       if (BGP_DEBUG (normal, NORMAL))
                    311:         zlog_debug ("%s OPEN has %s ORF capability"
                    312:                     " as %s for afi/safi: %d/%d",
                    313:                     peer->host, LOOKUP (orf_type_str, type),
                    314:                     LOOKUP (orf_mode_str, mode),
                    315:                     entry.mpc.afi, safi);
                    316: 
                    317:       if (hdr->code == CAPABILITY_CODE_ORF)
                    318:        {
                    319:           sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
                    320:           rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
                    321:        }
                    322:       else if (hdr->code == CAPABILITY_CODE_ORF_OLD)
                    323:        {
                    324:           sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
                    325:           rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
                    326:        }
                    327:       else
                    328:        {
                    329:          bgp_capability_orf_not_support (peer, afi, safi, type, mode);
                    330:          continue;
                    331:        }
                    332: 
                    333:       switch (mode)
                    334:        {
                    335:          case ORF_MODE_BOTH:
                    336:            SET_FLAG (peer->af_cap[afi][safi], sm_cap);
                    337:            SET_FLAG (peer->af_cap[afi][safi], rm_cap);
                    338:            break;
                    339:          case ORF_MODE_SEND:
                    340:            SET_FLAG (peer->af_cap[afi][safi], sm_cap);
                    341:            break;
                    342:          case ORF_MODE_RECEIVE:
                    343:            SET_FLAG (peer->af_cap[afi][safi], rm_cap);
                    344:            break;
                    345:        }
                    346:     }
                    347:   return 0;
                    348: }
                    349: 
                    350: static int
                    351: bgp_capability_orf (struct peer *peer, struct capability_header *hdr)
                    352: {
                    353:   struct stream *s = BGP_INPUT (peer);
                    354:   size_t end = stream_get_getp (s) + hdr->length;
                    355:   
                    356:   assert (stream_get_getp(s) + sizeof(struct capability_orf_entry) <= end);
                    357:   
                    358:   /* We must have at least one ORF entry, as the caller has already done
                    359:    * minimum length validation for the capability code - for ORF there must
                    360:    * at least one ORF entry (header and unknown number of pairs of bytes).
                    361:    */
                    362:   do
                    363:     {
                    364:       if (bgp_capability_orf_entry (peer, hdr) == -1)
                    365:         return -1;
                    366:     } 
                    367:   while (stream_get_getp(s) + sizeof(struct capability_orf_entry) < end);
                    368:   
                    369:   return 0;
                    370: }
                    371: 
                    372: static int
                    373: bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
                    374: {
                    375:   struct stream *s = BGP_INPUT (peer);
                    376:   u_int16_t restart_flag_time;
                    377:   int restart_bit = 0;
                    378:   size_t end = stream_get_getp (s) + caphdr->length;
                    379: 
                    380:   SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
                    381:   restart_flag_time = stream_getw(s);
                    382:   if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
                    383:     restart_bit = 1;
                    384:   UNSET_FLAG (restart_flag_time, 0xF000);
                    385:   peer->v_gr_restart = restart_flag_time;
                    386: 
                    387:   if (BGP_DEBUG (normal, NORMAL))
                    388:     {
                    389:       zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
                    390:       zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
                    391:                   peer->host, restart_bit ? " " : " not ",
                    392:                   peer->v_gr_restart);
                    393:     }
                    394: 
                    395:   while (stream_get_getp (s) + 4 < end)
                    396:     {
                    397:       afi_t afi = stream_getw (s);
                    398:       safi_t safi = stream_getc (s);
                    399:       u_char flag = stream_getc (s);
                    400:       
                    401:       if (!bgp_afi_safi_valid_indices (afi, &safi))
                    402:         {
                    403:           if (BGP_DEBUG (normal, NORMAL))
                    404:             zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
                    405:                         " Ignore the Graceful Restart capability",
                    406:                         peer->host, afi, safi);
                    407:         }
                    408:       else if (!peer->afc[afi][safi])
                    409:         {
                    410:           if (BGP_DEBUG (normal, NORMAL))
                    411:             zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
                    412:                         " Ignore the Graceful Restart capability",
                    413:                         peer->host, afi, safi);
                    414:         }
                    415:       else
                    416:         {
                    417:           if (BGP_DEBUG (normal, NORMAL))
                    418:             zlog_debug ("%s Address family %s is%spreserved", peer->host,
                    419:                         afi_safi_print (afi, safi),
                    420:                         CHECK_FLAG (peer->af_cap[afi][safi],
                    421:                                     PEER_CAP_RESTART_AF_PRESERVE_RCV)
                    422:                         ? " " : " not ");
                    423: 
                    424:           SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
                    425:           if (CHECK_FLAG (flag, RESTART_F_BIT))
                    426:             SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
                    427:           
                    428:         }
                    429:     }
                    430:   return 0;
                    431: }
                    432: 
                    433: static as_t
                    434: bgp_capability_as4 (struct peer *peer, struct capability_header *hdr)
                    435: {
                    436:   as_t as4 = stream_getl (BGP_INPUT(peer));
                    437:   
                    438:   if (BGP_DEBUG (as4, AS4))
                    439:     zlog_debug ("%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
                    440:                 peer->host, as4);
                    441:   SET_FLAG (peer->cap, PEER_CAP_AS4_RCV);
                    442:   
                    443:   return as4;
                    444: }
                    445: 
                    446: static const struct message capcode_str[] =
                    447: {
                    448:   { CAPABILITY_CODE_MP,                        "MultiProtocol Extensions"      },
                    449:   { CAPABILITY_CODE_REFRESH,           "Route Refresh"                 },
                    450:   { CAPABILITY_CODE_ORF,               "Cooperative Route Filtering"   },
                    451:   { CAPABILITY_CODE_RESTART,           "Graceful Restart"              },
                    452:   { CAPABILITY_CODE_AS4,               "4-octet AS number"             },
                    453:   { CAPABILITY_CODE_DYNAMIC,           "Dynamic"                       },
                    454:   { CAPABILITY_CODE_REFRESH_OLD,       "Route Refresh (Old)"           },
                    455:   { CAPABILITY_CODE_ORF_OLD,           "ORF (Old)"                     },
                    456: };
                    457: static const int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
                    458: 
                    459: /* Minimum sizes for length field of each cap (so not inc. the header) */
                    460: static const size_t cap_minsizes[] = 
                    461: {
                    462:   [CAPABILITY_CODE_MP]         = sizeof (struct capability_mp_data),
                    463:   [CAPABILITY_CODE_REFRESH]    = CAPABILITY_CODE_REFRESH_LEN,
                    464:   [CAPABILITY_CODE_ORF]                = sizeof (struct capability_orf_entry),
                    465:   [CAPABILITY_CODE_RESTART]    = sizeof (struct capability_gr),
                    466:   [CAPABILITY_CODE_AS4]                = CAPABILITY_CODE_AS4_LEN,
                    467:   [CAPABILITY_CODE_DYNAMIC]    = CAPABILITY_CODE_DYNAMIC_LEN,
                    468:   [CAPABILITY_CODE_REFRESH_OLD]        = CAPABILITY_CODE_REFRESH_LEN,
                    469:   [CAPABILITY_CODE_ORF_OLD]    = sizeof (struct capability_orf_entry),
                    470: };
                    471: 
                    472: /* Parse given capability.
                    473:  * XXX: This is reading into a stream, but not using stream API
                    474:  */
                    475: static int
                    476: bgp_capability_parse (struct peer *peer, size_t length, u_char **error)
                    477: {
                    478:   int ret;
                    479:   struct stream *s = BGP_INPUT (peer);
                    480:   size_t end = stream_get_getp (s) + length;
                    481:   
                    482:   assert (STREAM_READABLE (s) >= length);
                    483:   
                    484:   while (stream_get_getp (s) < end)
                    485:     {
                    486:       size_t start;
                    487:       u_char *sp = stream_pnt (s);
                    488:       struct capability_header caphdr;
                    489:       
                    490:       /* We need at least capability code and capability length. */
                    491:       if (stream_get_getp(s) + 2 > end)
                    492:        {
                    493:          zlog_info ("%s Capability length error (< header)", peer->host);
                    494:          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    495:          return -1;
                    496:        }
                    497:       
                    498:       caphdr.code = stream_getc (s);
                    499:       caphdr.length = stream_getc (s);
                    500:       start = stream_get_getp (s);
                    501:       
                    502:       /* Capability length check sanity check. */
                    503:       if (start + caphdr.length > end)
                    504:        {
                    505:          zlog_info ("%s Capability length error (< length)", peer->host);
                    506:          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    507:          return -1;
                    508:        }
                    509:       
                    510:       if (BGP_DEBUG (normal, NORMAL))
                    511:        zlog_debug ("%s OPEN has %s capability (%u), length %u",
                    512:                   peer->host,
                    513:                   LOOKUP (capcode_str, caphdr.code),
                    514:                   caphdr.code, caphdr.length);
                    515:       
                    516:       /* Length sanity check, type-specific, for known capabilities */
                    517:       switch (caphdr.code)
                    518:         {
                    519:           case CAPABILITY_CODE_MP:
                    520:           case CAPABILITY_CODE_REFRESH:
                    521:           case CAPABILITY_CODE_REFRESH_OLD:
                    522:           case CAPABILITY_CODE_ORF:
                    523:           case CAPABILITY_CODE_ORF_OLD:
                    524:           case CAPABILITY_CODE_RESTART:
                    525:           case CAPABILITY_CODE_AS4:
                    526:           case CAPABILITY_CODE_DYNAMIC:
                    527:               /* Check length. */
                    528:               if (caphdr.length < cap_minsizes[caphdr.code])
                    529:                 {
                    530:                   zlog_info ("%s %s Capability length error: got %u,"
                    531:                              " expected at least %u",
                    532:                              peer->host, 
                    533:                              LOOKUP (capcode_str, caphdr.code),
                    534:                              caphdr.length, 
                    535:                             (unsigned) cap_minsizes[caphdr.code]);
                    536:                   bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    537:                   return -1;
                    538:                 }
                    539:           /* we deliberately ignore unknown codes, see below */
                    540:           default:
                    541:             break;
                    542:         }
                    543:       
                    544:       switch (caphdr.code)
                    545:         {
                    546:           case CAPABILITY_CODE_MP:
                    547:             {
                    548:               /* Ignore capability when override-capability is set. */
                    549:               if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
                    550:                 {
                    551:                   /* Set negotiated value. */
                    552:                   ret = bgp_capability_mp (peer, &caphdr);
                    553: 
                    554:                   /* Unsupported Capability. */
                    555:                   if (ret < 0)
                    556:                     {
                    557:                       /* Store return data. */
                    558:                       memcpy (*error, sp, caphdr.length + 2);
                    559:                       *error += caphdr.length + 2;
                    560:                     }
                    561:                 }
                    562:             }
                    563:             break;
                    564:           case CAPABILITY_CODE_REFRESH:
                    565:           case CAPABILITY_CODE_REFRESH_OLD:
                    566:             {
                    567:               /* BGP refresh capability */
                    568:               if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
                    569:                 SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
                    570:               else
                    571:                 SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
                    572:             }
                    573:             break;
                    574:           case CAPABILITY_CODE_ORF:
                    575:           case CAPABILITY_CODE_ORF_OLD:
                    576:             if (bgp_capability_orf (peer, &caphdr))
                    577:               return -1;
                    578:             break;
                    579:           case CAPABILITY_CODE_RESTART:
                    580:             if (bgp_capability_restart (peer, &caphdr))
                    581:               return -1;
                    582:             break;
                    583:           case CAPABILITY_CODE_DYNAMIC:
                    584:             SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
                    585:             break;
                    586:           case CAPABILITY_CODE_AS4:
                    587:               /* Already handled as a special-case parsing of the capabilities
                    588:                * at the beginning of OPEN processing. So we care not a jot
                    589:                * for the value really, only error case.
                    590:                */
                    591:               if (!bgp_capability_as4 (peer, &caphdr))
                    592:                 return -1;
                    593:               break;            
                    594:           default:
                    595:             if (caphdr.code > 128)
                    596:               {
                    597:                 /* We don't send Notification for unknown vendor specific
                    598:                    capabilities.  It seems reasonable for now...  */
                    599:                 zlog_warn ("%s Vendor specific capability %d",
                    600:                            peer->host, caphdr.code);
                    601:               }
                    602:             else
                    603:               {
                    604:                 zlog_warn ("%s unrecognized capability code: %d - ignored",
                    605:                            peer->host, caphdr.code);
                    606:                 memcpy (*error, sp, caphdr.length + 2);
                    607:                 *error += caphdr.length + 2;
                    608:               }
                    609:           }
                    610:       if (stream_get_getp(s) != (start + caphdr.length))
                    611:         {
                    612:           if (stream_get_getp(s) > (start + caphdr.length))
                    613:             zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
                    614:                        peer->host, LOOKUP (capcode_str, caphdr.code),
                    615:                        caphdr.length);
                    616:           stream_set_getp (s, start + caphdr.length);
                    617:         }
                    618:     }
                    619:   return 0;
                    620: }
                    621: 
                    622: static int
                    623: bgp_auth_parse (struct peer *peer, size_t length)
                    624: {
                    625:   bgp_notify_send (peer, 
                    626:                   BGP_NOTIFY_OPEN_ERR, 
                    627:                   BGP_NOTIFY_OPEN_AUTH_FAILURE); 
                    628:   return -1;
                    629: }
                    630: 
                    631: static int
                    632: strict_capability_same (struct peer *peer)
                    633: {
                    634:   int i, j;
                    635: 
                    636:   for (i = AFI_IP; i < AFI_MAX; i++)
                    637:     for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
                    638:       if (peer->afc[i][j] != peer->afc_nego[i][j])
                    639:        return 0;
                    640:   return 1;
                    641: }
                    642: 
                    643: /* peek into option, stores ASN to *as4 if the AS4 capability was found.
                    644:  * Returns  0 if no as4 found, as4cap value otherwise.
                    645:  */
                    646: as_t
                    647: peek_for_as4_capability (struct peer *peer, u_char length)
                    648: {
                    649:   struct stream *s = BGP_INPUT (peer);
                    650:   size_t orig_getp = stream_get_getp (s);
                    651:   size_t end = orig_getp + length;
                    652:   as_t as4 = 0;
                    653:   
                    654:   /* The full capability parser will better flag the error.. */
                    655:   if (STREAM_READABLE(s) < length)
                    656:     return 0;
                    657: 
                    658:   if (BGP_DEBUG (as4, AS4))
                    659:     zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
                    660:                 " peeking for as4",
                    661:                peer->host, length);
                    662:   /* the error cases we DONT handle, we ONLY try to read as4 out of
                    663:    * correctly formatted options.
                    664:    */
                    665:   while (stream_get_getp(s) < end) 
                    666:     {
                    667:       u_char opt_type;
                    668:       u_char opt_length;
                    669:       
                    670:       /* Check the length. */
                    671:       if (stream_get_getp (s) + 2 > end)
                    672:         goto end;
                    673:       
                    674:       /* Fetch option type and length. */
                    675:       opt_type = stream_getc (s);
                    676:       opt_length = stream_getc (s);
                    677:       
                    678:       /* Option length check. */
                    679:       if (stream_get_getp (s) + opt_length > end)
                    680:         goto end;
                    681:       
                    682:       if (opt_type == BGP_OPEN_OPT_CAP)
                    683:         {
                    684:           unsigned long capd_start = stream_get_getp (s);
                    685:           unsigned long capd_end = capd_start + opt_length;
                    686:           
                    687:           assert (capd_end <= end);
                    688:           
                    689:          while (stream_get_getp (s) < capd_end)
                    690:            {
                    691:              struct capability_header hdr;
                    692:              
                    693:              if (stream_get_getp (s) + 2 > capd_end)
                    694:                 goto end;
                    695:               
                    696:               hdr.code = stream_getc (s);
                    697:               hdr.length = stream_getc (s);
                    698:               
                    699:              if ((stream_get_getp(s) +  hdr.length) > capd_end)
                    700:                goto end;
                    701: 
                    702:              if (hdr.code == CAPABILITY_CODE_AS4)
                    703:                {
                    704:                  if (hdr.length != CAPABILITY_CODE_AS4_LEN)
                    705:                    goto end;
                    706:                   
                    707:                  if (BGP_DEBUG (as4, AS4))
                    708:                    zlog_info ("[AS4] found AS4 capability, about to parse");
                    709:                  as4 = bgp_capability_as4 (peer, &hdr);
                    710:                  
                    711:                  goto end;
                    712:                 }
                    713:               stream_forward_getp (s, hdr.length);
                    714:            }
                    715:        }
                    716:     }
                    717: 
                    718: end:
                    719:   stream_set_getp (s, orig_getp);
                    720:   return as4;
                    721: }
                    722: 
                    723: /* Parse open option */
                    724: int
                    725: bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
                    726: {
                    727:   int ret;
                    728:   u_char *error;
                    729:   u_char error_data[BGP_MAX_PACKET_SIZE];
                    730:   struct stream *s = BGP_INPUT(peer);
                    731:   size_t end = stream_get_getp (s) + length;
                    732: 
                    733:   ret = 0;
                    734:   error = error_data;
                    735: 
                    736:   if (BGP_DEBUG (normal, NORMAL))
                    737:     zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
                    738:               peer->host, length);
                    739:   
                    740:   while (stream_get_getp(s) < end)
                    741:     {
                    742:       u_char opt_type;
                    743:       u_char opt_length;
                    744:       
                    745:       /* Must have at least an OPEN option header */
                    746:       if (STREAM_READABLE(s) < 2)
                    747:        {
                    748:          zlog_info ("%s Option length error", peer->host);
                    749:          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    750:          return -1;
                    751:        }
                    752: 
                    753:       /* Fetch option type and length. */
                    754:       opt_type = stream_getc (s);
                    755:       opt_length = stream_getc (s);
                    756:       
                    757:       /* Option length check. */
                    758:       if (STREAM_READABLE (s) < opt_length)
                    759:        {
                    760:          zlog_info ("%s Option length error", peer->host);
                    761:          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    762:          return -1;
                    763:        }
                    764: 
                    765:       if (BGP_DEBUG (normal, NORMAL))
                    766:        zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
                    767:                   peer->host, opt_type,
                    768:                   opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
                    769:                   opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
                    770:                   opt_length);
                    771:   
                    772:       switch (opt_type)
                    773:        {
                    774:        case BGP_OPEN_OPT_AUTH:
                    775:          ret = bgp_auth_parse (peer, opt_length);
                    776:          break;
                    777:        case BGP_OPEN_OPT_CAP:
                    778:          ret = bgp_capability_parse (peer, opt_length, &error);
                    779:          *capability = 1;
                    780:          break;
                    781:        default:
                    782:          bgp_notify_send (peer, 
                    783:                           BGP_NOTIFY_OPEN_ERR, 
                    784:                           BGP_NOTIFY_OPEN_UNSUP_PARAM); 
                    785:          ret = -1;
                    786:          break;
                    787:        }
                    788: 
                    789:       /* Parse error.  To accumulate all unsupported capability codes,
                    790:          bgp_capability_parse does not return -1 when encounter
                    791:          unsupported capability code.  To detect that, please check
                    792:          error and erro_data pointer, like below.  */
                    793:       if (ret < 0)
                    794:        return -1;
                    795:     }
                    796: 
                    797:   /* All OPEN option is parsed.  Check capability when strict compare
                    798:      flag is enabled.*/
                    799:   if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
                    800:     {
                    801:       /* If Unsupported Capability exists. */
                    802:       if (error != error_data)
                    803:        {
                    804:          bgp_notify_send_with_data (peer, 
                    805:                                     BGP_NOTIFY_OPEN_ERR, 
                    806:                                     BGP_NOTIFY_OPEN_UNSUP_CAPBL, 
                    807:                                     error_data, error - error_data);
                    808:          return -1;
                    809:        }
                    810: 
                    811:       /* Check local capability does not negotiated with remote
                    812:          peer. */
                    813:       if (! strict_capability_same (peer))
                    814:        {
                    815:          bgp_notify_send (peer, 
                    816:                           BGP_NOTIFY_OPEN_ERR, 
                    817:                           BGP_NOTIFY_OPEN_UNSUP_CAPBL);
                    818:          return -1;
                    819:        }
                    820:     }
                    821: 
                    822:   /* Check there is no common capability send Unsupported Capability
                    823:      error. */
                    824:   if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
                    825:     {
                    826:       if (! peer->afc_nego[AFI_IP][SAFI_UNICAST] 
                    827:          && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
                    828:          && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
                    829:          && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
                    830:          && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
                    831:        {
                    832:          plog_err (peer->log, "%s [Error] No common capability", peer->host);
                    833: 
                    834:          if (error != error_data)
                    835: 
                    836:            bgp_notify_send_with_data (peer, 
                    837:                                       BGP_NOTIFY_OPEN_ERR, 
                    838:                                       BGP_NOTIFY_OPEN_UNSUP_CAPBL, 
                    839:                                       error_data, error - error_data);
                    840:          else
                    841:            bgp_notify_send (peer, 
                    842:                             BGP_NOTIFY_OPEN_ERR, 
                    843:                             BGP_NOTIFY_OPEN_UNSUP_CAPBL);
                    844:          return -1;
                    845:        }
                    846:     }
                    847:   return 0;
                    848: }
                    849: 
                    850: static void
                    851: bgp_open_capability_orf (struct stream *s, struct peer *peer,
                    852:                          afi_t afi, safi_t safi, u_char code)
                    853: {
                    854:   u_char cap_len;
                    855:   u_char orf_len;
                    856:   unsigned long capp;
                    857:   unsigned long orfp;
                    858:   unsigned long numberp;
                    859:   int number_of_orfs = 0;
                    860: 
                    861:   if (safi == SAFI_MPLS_VPN)
                    862:     safi = BGP_SAFI_VPNV4;
                    863: 
                    864:   stream_putc (s, BGP_OPEN_OPT_CAP);
                    865:   capp = stream_get_endp (s);           /* Set Capability Len Pointer */
                    866:   stream_putc (s, 0);                   /* Capability Length */
                    867:   stream_putc (s, code);                /* Capability Code */
                    868:   orfp = stream_get_endp (s);           /* Set ORF Len Pointer */
                    869:   stream_putc (s, 0);                   /* ORF Length */
                    870:   stream_putw (s, afi);
                    871:   stream_putc (s, 0);
                    872:   stream_putc (s, safi);
                    873:   numberp = stream_get_endp (s);        /* Set Number Pointer */
                    874:   stream_putc (s, 0);                   /* Number of ORFs */
                    875: 
                    876:   /* Address Prefix ORF */
                    877:   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
                    878:       || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
                    879:     {
                    880:       stream_putc (s, (code == CAPABILITY_CODE_ORF ?
                    881:                   ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
                    882: 
                    883:       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
                    884:          && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
                    885:        {
                    886:          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
                    887:          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
                    888:          stream_putc (s, ORF_MODE_BOTH);
                    889:        }
                    890:       else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
                    891:        {
                    892:          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
                    893:          stream_putc (s, ORF_MODE_SEND);
                    894:        }
                    895:       else
                    896:        {
                    897:          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
                    898:          stream_putc (s, ORF_MODE_RECEIVE);
                    899:        }
                    900:       number_of_orfs++;
                    901:     }
                    902: 
                    903:   /* Total Number of ORFs. */
                    904:   stream_putc_at (s, numberp, number_of_orfs);
                    905: 
                    906:   /* Total ORF Len. */
                    907:   orf_len = stream_get_endp (s) - orfp - 1;
                    908:   stream_putc_at (s, orfp, orf_len);
                    909: 
                    910:   /* Total Capability Len. */
                    911:   cap_len = stream_get_endp (s) - capp - 1;
                    912:   stream_putc_at (s, capp, cap_len);
                    913: }
                    914: 
                    915: /* Fill in capability open option to the packet. */
                    916: void
                    917: bgp_open_capability (struct stream *s, struct peer *peer)
                    918: {
                    919:   u_char len;
                    920:   unsigned long cp;
                    921:   afi_t afi;
                    922:   safi_t safi;
                    923:   as_t local_as;
                    924: 
                    925:   /* Remember current pointer for Opt Parm Len. */
                    926:   cp = stream_get_endp (s);
                    927: 
                    928:   /* Opt Parm Len. */
                    929:   stream_putc (s, 0);
                    930: 
                    931:   /* Do not send capability. */
                    932:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN) 
                    933:       || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
                    934:     return;
                    935: 
                    936:   /* IPv4 unicast. */
                    937:   if (peer->afc[AFI_IP][SAFI_UNICAST])
                    938:     {
                    939:       peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
                    940:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    941:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    942:       stream_putc (s, CAPABILITY_CODE_MP);
                    943:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    944:       stream_putw (s, AFI_IP);
                    945:       stream_putc (s, 0);
                    946:       stream_putc (s, SAFI_UNICAST);
                    947:     }
                    948:   /* IPv4 multicast. */
                    949:   if (peer->afc[AFI_IP][SAFI_MULTICAST])
                    950:     {
                    951:       peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
                    952:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    953:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    954:       stream_putc (s, CAPABILITY_CODE_MP);
                    955:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    956:       stream_putw (s, AFI_IP);
                    957:       stream_putc (s, 0);
                    958:       stream_putc (s, SAFI_MULTICAST);
                    959:     }
                    960:   /* IPv4 VPN */
                    961:   if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
                    962:     {
                    963:       peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
                    964:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    965:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    966:       stream_putc (s, CAPABILITY_CODE_MP);
                    967:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    968:       stream_putw (s, AFI_IP);
                    969:       stream_putc (s, 0);
                    970:       stream_putc (s, BGP_SAFI_VPNV4);
                    971:     }
                    972: #ifdef HAVE_IPV6
                    973:   /* IPv6 unicast. */
                    974:   if (peer->afc[AFI_IP6][SAFI_UNICAST])
                    975:     {
                    976:       peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
                    977:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    978:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    979:       stream_putc (s, CAPABILITY_CODE_MP);
                    980:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    981:       stream_putw (s, AFI_IP6);
                    982:       stream_putc (s, 0);
                    983:       stream_putc (s, SAFI_UNICAST);
                    984:     }
                    985:   /* IPv6 multicast. */
                    986:   if (peer->afc[AFI_IP6][SAFI_MULTICAST])
                    987:     {
                    988:       peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
                    989:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    990:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    991:       stream_putc (s, CAPABILITY_CODE_MP);
                    992:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    993:       stream_putw (s, AFI_IP6);
                    994:       stream_putc (s, 0);
                    995:       stream_putc (s, SAFI_MULTICAST);
                    996:     }
                    997: #endif /* HAVE_IPV6 */
                    998: 
                    999:   /* Route refresh. */
                   1000:   SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
                   1001:   stream_putc (s, BGP_OPEN_OPT_CAP);
                   1002:   stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
                   1003:   stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
                   1004:   stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
                   1005:   stream_putc (s, BGP_OPEN_OPT_CAP);
                   1006:   stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
                   1007:   stream_putc (s, CAPABILITY_CODE_REFRESH);
                   1008:   stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
                   1009: 
                   1010:   /* AS4 */
                   1011:   SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
                   1012:   stream_putc (s, BGP_OPEN_OPT_CAP);
                   1013:   stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
                   1014:   stream_putc (s, CAPABILITY_CODE_AS4);
                   1015:   stream_putc (s, CAPABILITY_CODE_AS4_LEN);
                   1016:   if ( peer->change_local_as )
                   1017:     local_as = peer->change_local_as;
                   1018:   else
                   1019:     local_as = peer->local_as;
                   1020:   stream_putl (s, local_as );
                   1021: 
                   1022:   /* ORF capability. */
                   1023:   for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
                   1024:     for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
                   1025:       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
                   1026:          || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
                   1027:        {
                   1028:          bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
                   1029:          bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
                   1030:        }
                   1031: 
                   1032:   /* Dynamic capability. */
                   1033:   if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
                   1034:     {
                   1035:       SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
                   1036:       stream_putc (s, BGP_OPEN_OPT_CAP);
                   1037:       stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
                   1038:       stream_putc (s, CAPABILITY_CODE_DYNAMIC);
                   1039:       stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
                   1040:     }
                   1041: 
                   1042:   /* Graceful restart capability */
                   1043:   if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
                   1044:     {
                   1045:       SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
                   1046:       stream_putc (s, BGP_OPEN_OPT_CAP);
                   1047:       stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
                   1048:       stream_putc (s, CAPABILITY_CODE_RESTART);
                   1049:       stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
                   1050:       stream_putw (s, peer->bgp->restart_time);
                   1051:      }
                   1052: 
                   1053:   /* Total Opt Parm Len. */
                   1054:   len = stream_get_endp (s) - cp - 1;
                   1055:   stream_putc_at (s, cp, len);
                   1056: }

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