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

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: {
1.1.1.2 ! misho     436:   SET_FLAG (peer->cap, PEER_CAP_AS4_RCV);
        !           437:   
        !           438:   if (hdr->length != CAPABILITY_CODE_AS4_LEN)
        !           439:     {
        !           440:       zlog_err ("%s AS4 capability has incorrect data length %d",
        !           441:                 peer->host, hdr->length);
        !           442:       return 0;
        !           443:     }
        !           444:   
1.1       misho     445:   as_t as4 = stream_getl (BGP_INPUT(peer));
                    446:   
                    447:   if (BGP_DEBUG (as4, AS4))
                    448:     zlog_debug ("%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
                    449:                 peer->host, as4);
                    450:   return as4;
                    451: }
                    452: 
                    453: static const struct message capcode_str[] =
                    454: {
                    455:   { CAPABILITY_CODE_MP,                        "MultiProtocol Extensions"      },
                    456:   { CAPABILITY_CODE_REFRESH,           "Route Refresh"                 },
                    457:   { CAPABILITY_CODE_ORF,               "Cooperative Route Filtering"   },
                    458:   { CAPABILITY_CODE_RESTART,           "Graceful Restart"              },
                    459:   { CAPABILITY_CODE_AS4,               "4-octet AS number"             },
                    460:   { CAPABILITY_CODE_DYNAMIC,           "Dynamic"                       },
                    461:   { CAPABILITY_CODE_REFRESH_OLD,       "Route Refresh (Old)"           },
                    462:   { CAPABILITY_CODE_ORF_OLD,           "ORF (Old)"                     },
                    463: };
                    464: static const int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
                    465: 
                    466: /* Minimum sizes for length field of each cap (so not inc. the header) */
                    467: static const size_t cap_minsizes[] = 
                    468: {
                    469:   [CAPABILITY_CODE_MP]         = sizeof (struct capability_mp_data),
                    470:   [CAPABILITY_CODE_REFRESH]    = CAPABILITY_CODE_REFRESH_LEN,
                    471:   [CAPABILITY_CODE_ORF]                = sizeof (struct capability_orf_entry),
                    472:   [CAPABILITY_CODE_RESTART]    = sizeof (struct capability_gr),
                    473:   [CAPABILITY_CODE_AS4]                = CAPABILITY_CODE_AS4_LEN,
                    474:   [CAPABILITY_CODE_DYNAMIC]    = CAPABILITY_CODE_DYNAMIC_LEN,
                    475:   [CAPABILITY_CODE_REFRESH_OLD]        = CAPABILITY_CODE_REFRESH_LEN,
                    476:   [CAPABILITY_CODE_ORF_OLD]    = sizeof (struct capability_orf_entry),
                    477: };
                    478: 
                    479: /* Parse given capability.
                    480:  * XXX: This is reading into a stream, but not using stream API
                    481:  */
                    482: static int
                    483: bgp_capability_parse (struct peer *peer, size_t length, u_char **error)
                    484: {
                    485:   int ret;
                    486:   struct stream *s = BGP_INPUT (peer);
                    487:   size_t end = stream_get_getp (s) + length;
                    488:   
                    489:   assert (STREAM_READABLE (s) >= length);
                    490:   
                    491:   while (stream_get_getp (s) < end)
                    492:     {
                    493:       size_t start;
                    494:       u_char *sp = stream_pnt (s);
                    495:       struct capability_header caphdr;
                    496:       
                    497:       /* We need at least capability code and capability length. */
                    498:       if (stream_get_getp(s) + 2 > end)
                    499:        {
                    500:          zlog_info ("%s Capability length error (< header)", peer->host);
                    501:          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    502:          return -1;
                    503:        }
                    504:       
                    505:       caphdr.code = stream_getc (s);
                    506:       caphdr.length = stream_getc (s);
                    507:       start = stream_get_getp (s);
                    508:       
                    509:       /* Capability length check sanity check. */
                    510:       if (start + caphdr.length > end)
                    511:        {
                    512:          zlog_info ("%s Capability length error (< length)", peer->host);
                    513:          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    514:          return -1;
                    515:        }
                    516:       
                    517:       if (BGP_DEBUG (normal, NORMAL))
                    518:        zlog_debug ("%s OPEN has %s capability (%u), length %u",
                    519:                   peer->host,
                    520:                   LOOKUP (capcode_str, caphdr.code),
                    521:                   caphdr.code, caphdr.length);
                    522:       
                    523:       /* Length sanity check, type-specific, for known capabilities */
                    524:       switch (caphdr.code)
                    525:         {
                    526:           case CAPABILITY_CODE_MP:
                    527:           case CAPABILITY_CODE_REFRESH:
                    528:           case CAPABILITY_CODE_REFRESH_OLD:
                    529:           case CAPABILITY_CODE_ORF:
                    530:           case CAPABILITY_CODE_ORF_OLD:
                    531:           case CAPABILITY_CODE_RESTART:
                    532:           case CAPABILITY_CODE_AS4:
                    533:           case CAPABILITY_CODE_DYNAMIC:
                    534:               /* Check length. */
                    535:               if (caphdr.length < cap_minsizes[caphdr.code])
                    536:                 {
                    537:                   zlog_info ("%s %s Capability length error: got %u,"
                    538:                              " expected at least %u",
                    539:                              peer->host, 
                    540:                              LOOKUP (capcode_str, caphdr.code),
                    541:                              caphdr.length, 
                    542:                             (unsigned) cap_minsizes[caphdr.code]);
                    543:                   bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    544:                   return -1;
                    545:                 }
                    546:           /* we deliberately ignore unknown codes, see below */
                    547:           default:
                    548:             break;
                    549:         }
                    550:       
                    551:       switch (caphdr.code)
                    552:         {
                    553:           case CAPABILITY_CODE_MP:
                    554:             {
                    555:               /* Ignore capability when override-capability is set. */
                    556:               if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
                    557:                 {
                    558:                   /* Set negotiated value. */
                    559:                   ret = bgp_capability_mp (peer, &caphdr);
                    560: 
                    561:                   /* Unsupported Capability. */
                    562:                   if (ret < 0)
                    563:                     {
                    564:                       /* Store return data. */
                    565:                       memcpy (*error, sp, caphdr.length + 2);
                    566:                       *error += caphdr.length + 2;
                    567:                     }
                    568:                 }
                    569:             }
                    570:             break;
                    571:           case CAPABILITY_CODE_REFRESH:
                    572:           case CAPABILITY_CODE_REFRESH_OLD:
                    573:             {
                    574:               /* BGP refresh capability */
                    575:               if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
                    576:                 SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
                    577:               else
                    578:                 SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
                    579:             }
                    580:             break;
                    581:           case CAPABILITY_CODE_ORF:
                    582:           case CAPABILITY_CODE_ORF_OLD:
                    583:             if (bgp_capability_orf (peer, &caphdr))
                    584:               return -1;
                    585:             break;
                    586:           case CAPABILITY_CODE_RESTART:
                    587:             if (bgp_capability_restart (peer, &caphdr))
                    588:               return -1;
                    589:             break;
                    590:           case CAPABILITY_CODE_DYNAMIC:
                    591:             SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
                    592:             break;
                    593:           case CAPABILITY_CODE_AS4:
                    594:               /* Already handled as a special-case parsing of the capabilities
                    595:                * at the beginning of OPEN processing. So we care not a jot
                    596:                * for the value really, only error case.
                    597:                */
                    598:               if (!bgp_capability_as4 (peer, &caphdr))
                    599:                 return -1;
                    600:               break;            
                    601:           default:
                    602:             if (caphdr.code > 128)
                    603:               {
                    604:                 /* We don't send Notification for unknown vendor specific
                    605:                    capabilities.  It seems reasonable for now...  */
                    606:                 zlog_warn ("%s Vendor specific capability %d",
                    607:                            peer->host, caphdr.code);
                    608:               }
                    609:             else
                    610:               {
                    611:                 zlog_warn ("%s unrecognized capability code: %d - ignored",
                    612:                            peer->host, caphdr.code);
                    613:                 memcpy (*error, sp, caphdr.length + 2);
                    614:                 *error += caphdr.length + 2;
                    615:               }
                    616:           }
                    617:       if (stream_get_getp(s) != (start + caphdr.length))
                    618:         {
                    619:           if (stream_get_getp(s) > (start + caphdr.length))
                    620:             zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
                    621:                        peer->host, LOOKUP (capcode_str, caphdr.code),
                    622:                        caphdr.length);
                    623:           stream_set_getp (s, start + caphdr.length);
                    624:         }
                    625:     }
                    626:   return 0;
                    627: }
                    628: 
                    629: static int
                    630: bgp_auth_parse (struct peer *peer, size_t length)
                    631: {
                    632:   bgp_notify_send (peer, 
                    633:                   BGP_NOTIFY_OPEN_ERR, 
                    634:                   BGP_NOTIFY_OPEN_AUTH_FAILURE); 
                    635:   return -1;
                    636: }
                    637: 
                    638: static int
                    639: strict_capability_same (struct peer *peer)
                    640: {
                    641:   int i, j;
                    642: 
                    643:   for (i = AFI_IP; i < AFI_MAX; i++)
                    644:     for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
                    645:       if (peer->afc[i][j] != peer->afc_nego[i][j])
                    646:        return 0;
                    647:   return 1;
                    648: }
                    649: 
                    650: /* peek into option, stores ASN to *as4 if the AS4 capability was found.
                    651:  * Returns  0 if no as4 found, as4cap value otherwise.
                    652:  */
                    653: as_t
                    654: peek_for_as4_capability (struct peer *peer, u_char length)
                    655: {
                    656:   struct stream *s = BGP_INPUT (peer);
                    657:   size_t orig_getp = stream_get_getp (s);
                    658:   size_t end = orig_getp + length;
                    659:   as_t as4 = 0;
                    660:   
                    661:   /* The full capability parser will better flag the error.. */
                    662:   if (STREAM_READABLE(s) < length)
                    663:     return 0;
                    664: 
                    665:   if (BGP_DEBUG (as4, AS4))
                    666:     zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
                    667:                 " peeking for as4",
                    668:                peer->host, length);
                    669:   /* the error cases we DONT handle, we ONLY try to read as4 out of
                    670:    * correctly formatted options.
                    671:    */
                    672:   while (stream_get_getp(s) < end) 
                    673:     {
                    674:       u_char opt_type;
                    675:       u_char opt_length;
                    676:       
                    677:       /* Check the length. */
                    678:       if (stream_get_getp (s) + 2 > end)
                    679:         goto end;
                    680:       
                    681:       /* Fetch option type and length. */
                    682:       opt_type = stream_getc (s);
                    683:       opt_length = stream_getc (s);
                    684:       
                    685:       /* Option length check. */
                    686:       if (stream_get_getp (s) + opt_length > end)
                    687:         goto end;
                    688:       
                    689:       if (opt_type == BGP_OPEN_OPT_CAP)
                    690:         {
                    691:           unsigned long capd_start = stream_get_getp (s);
                    692:           unsigned long capd_end = capd_start + opt_length;
                    693:           
                    694:           assert (capd_end <= end);
                    695:           
                    696:          while (stream_get_getp (s) < capd_end)
                    697:            {
                    698:              struct capability_header hdr;
                    699:              
                    700:              if (stream_get_getp (s) + 2 > capd_end)
                    701:                 goto end;
                    702:               
                    703:               hdr.code = stream_getc (s);
                    704:               hdr.length = stream_getc (s);
                    705:               
                    706:              if ((stream_get_getp(s) +  hdr.length) > capd_end)
                    707:                goto end;
                    708: 
                    709:              if (hdr.code == CAPABILITY_CODE_AS4)
                    710:                {
                    711:                  if (BGP_DEBUG (as4, AS4))
                    712:                    zlog_info ("[AS4] found AS4 capability, about to parse");
                    713:                  as4 = bgp_capability_as4 (peer, &hdr);
                    714:                  
                    715:                  goto end;
                    716:                 }
                    717:               stream_forward_getp (s, hdr.length);
                    718:            }
                    719:        }
                    720:     }
                    721: 
                    722: end:
                    723:   stream_set_getp (s, orig_getp);
                    724:   return as4;
                    725: }
                    726: 
                    727: /* Parse open option */
                    728: int
                    729: bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
                    730: {
                    731:   int ret;
                    732:   u_char *error;
                    733:   u_char error_data[BGP_MAX_PACKET_SIZE];
                    734:   struct stream *s = BGP_INPUT(peer);
                    735:   size_t end = stream_get_getp (s) + length;
                    736: 
                    737:   ret = 0;
                    738:   error = error_data;
                    739: 
                    740:   if (BGP_DEBUG (normal, NORMAL))
                    741:     zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
                    742:               peer->host, length);
                    743:   
                    744:   while (stream_get_getp(s) < end)
                    745:     {
                    746:       u_char opt_type;
                    747:       u_char opt_length;
                    748:       
                    749:       /* Must have at least an OPEN option header */
                    750:       if (STREAM_READABLE(s) < 2)
                    751:        {
                    752:          zlog_info ("%s Option length error", peer->host);
                    753:          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    754:          return -1;
                    755:        }
                    756: 
                    757:       /* Fetch option type and length. */
                    758:       opt_type = stream_getc (s);
                    759:       opt_length = stream_getc (s);
                    760:       
                    761:       /* Option length check. */
                    762:       if (STREAM_READABLE (s) < opt_length)
                    763:        {
                    764:          zlog_info ("%s Option length error", peer->host);
                    765:          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
                    766:          return -1;
                    767:        }
                    768: 
                    769:       if (BGP_DEBUG (normal, NORMAL))
                    770:        zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
                    771:                   peer->host, opt_type,
                    772:                   opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
                    773:                   opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
                    774:                   opt_length);
                    775:   
                    776:       switch (opt_type)
                    777:        {
                    778:        case BGP_OPEN_OPT_AUTH:
                    779:          ret = bgp_auth_parse (peer, opt_length);
                    780:          break;
                    781:        case BGP_OPEN_OPT_CAP:
                    782:          ret = bgp_capability_parse (peer, opt_length, &error);
                    783:          *capability = 1;
                    784:          break;
                    785:        default:
                    786:          bgp_notify_send (peer, 
                    787:                           BGP_NOTIFY_OPEN_ERR, 
                    788:                           BGP_NOTIFY_OPEN_UNSUP_PARAM); 
                    789:          ret = -1;
                    790:          break;
                    791:        }
                    792: 
                    793:       /* Parse error.  To accumulate all unsupported capability codes,
                    794:          bgp_capability_parse does not return -1 when encounter
                    795:          unsupported capability code.  To detect that, please check
                    796:          error and erro_data pointer, like below.  */
                    797:       if (ret < 0)
                    798:        return -1;
                    799:     }
                    800: 
                    801:   /* All OPEN option is parsed.  Check capability when strict compare
                    802:      flag is enabled.*/
                    803:   if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
                    804:     {
                    805:       /* If Unsupported Capability exists. */
                    806:       if (error != error_data)
                    807:        {
                    808:          bgp_notify_send_with_data (peer, 
                    809:                                     BGP_NOTIFY_OPEN_ERR, 
                    810:                                     BGP_NOTIFY_OPEN_UNSUP_CAPBL, 
                    811:                                     error_data, error - error_data);
                    812:          return -1;
                    813:        }
                    814: 
                    815:       /* Check local capability does not negotiated with remote
                    816:          peer. */
                    817:       if (! strict_capability_same (peer))
                    818:        {
                    819:          bgp_notify_send (peer, 
                    820:                           BGP_NOTIFY_OPEN_ERR, 
                    821:                           BGP_NOTIFY_OPEN_UNSUP_CAPBL);
                    822:          return -1;
                    823:        }
                    824:     }
                    825: 
                    826:   /* Check there is no common capability send Unsupported Capability
                    827:      error. */
                    828:   if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
                    829:     {
                    830:       if (! peer->afc_nego[AFI_IP][SAFI_UNICAST] 
                    831:          && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
                    832:          && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
                    833:          && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
                    834:          && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
                    835:        {
                    836:          plog_err (peer->log, "%s [Error] No common capability", peer->host);
                    837: 
                    838:          if (error != error_data)
                    839: 
                    840:            bgp_notify_send_with_data (peer, 
                    841:                                       BGP_NOTIFY_OPEN_ERR, 
                    842:                                       BGP_NOTIFY_OPEN_UNSUP_CAPBL, 
                    843:                                       error_data, error - error_data);
                    844:          else
                    845:            bgp_notify_send (peer, 
                    846:                             BGP_NOTIFY_OPEN_ERR, 
                    847:                             BGP_NOTIFY_OPEN_UNSUP_CAPBL);
                    848:          return -1;
                    849:        }
                    850:     }
                    851:   return 0;
                    852: }
                    853: 
                    854: static void
                    855: bgp_open_capability_orf (struct stream *s, struct peer *peer,
                    856:                          afi_t afi, safi_t safi, u_char code)
                    857: {
                    858:   u_char cap_len;
                    859:   u_char orf_len;
                    860:   unsigned long capp;
                    861:   unsigned long orfp;
                    862:   unsigned long numberp;
                    863:   int number_of_orfs = 0;
                    864: 
                    865:   if (safi == SAFI_MPLS_VPN)
                    866:     safi = BGP_SAFI_VPNV4;
                    867: 
                    868:   stream_putc (s, BGP_OPEN_OPT_CAP);
                    869:   capp = stream_get_endp (s);           /* Set Capability Len Pointer */
                    870:   stream_putc (s, 0);                   /* Capability Length */
                    871:   stream_putc (s, code);                /* Capability Code */
                    872:   orfp = stream_get_endp (s);           /* Set ORF Len Pointer */
                    873:   stream_putc (s, 0);                   /* ORF Length */
                    874:   stream_putw (s, afi);
                    875:   stream_putc (s, 0);
                    876:   stream_putc (s, safi);
                    877:   numberp = stream_get_endp (s);        /* Set Number Pointer */
                    878:   stream_putc (s, 0);                   /* Number of ORFs */
                    879: 
                    880:   /* Address Prefix ORF */
                    881:   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
                    882:       || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
                    883:     {
                    884:       stream_putc (s, (code == CAPABILITY_CODE_ORF ?
                    885:                   ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
                    886: 
                    887:       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
                    888:          && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
                    889:        {
                    890:          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
                    891:          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
                    892:          stream_putc (s, ORF_MODE_BOTH);
                    893:        }
                    894:       else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
                    895:        {
                    896:          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
                    897:          stream_putc (s, ORF_MODE_SEND);
                    898:        }
                    899:       else
                    900:        {
                    901:          SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
                    902:          stream_putc (s, ORF_MODE_RECEIVE);
                    903:        }
                    904:       number_of_orfs++;
                    905:     }
                    906: 
                    907:   /* Total Number of ORFs. */
                    908:   stream_putc_at (s, numberp, number_of_orfs);
                    909: 
                    910:   /* Total ORF Len. */
                    911:   orf_len = stream_get_endp (s) - orfp - 1;
                    912:   stream_putc_at (s, orfp, orf_len);
                    913: 
                    914:   /* Total Capability Len. */
                    915:   cap_len = stream_get_endp (s) - capp - 1;
                    916:   stream_putc_at (s, capp, cap_len);
                    917: }
                    918: 
                    919: /* Fill in capability open option to the packet. */
                    920: void
                    921: bgp_open_capability (struct stream *s, struct peer *peer)
                    922: {
                    923:   u_char len;
                    924:   unsigned long cp;
                    925:   afi_t afi;
                    926:   safi_t safi;
                    927:   as_t local_as;
                    928: 
                    929:   /* Remember current pointer for Opt Parm Len. */
                    930:   cp = stream_get_endp (s);
                    931: 
                    932:   /* Opt Parm Len. */
                    933:   stream_putc (s, 0);
                    934: 
                    935:   /* Do not send capability. */
                    936:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN) 
                    937:       || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
                    938:     return;
                    939: 
                    940:   /* IPv4 unicast. */
                    941:   if (peer->afc[AFI_IP][SAFI_UNICAST])
                    942:     {
                    943:       peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
                    944:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    945:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    946:       stream_putc (s, CAPABILITY_CODE_MP);
                    947:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    948:       stream_putw (s, AFI_IP);
                    949:       stream_putc (s, 0);
                    950:       stream_putc (s, SAFI_UNICAST);
                    951:     }
                    952:   /* IPv4 multicast. */
                    953:   if (peer->afc[AFI_IP][SAFI_MULTICAST])
                    954:     {
                    955:       peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
                    956:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    957:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    958:       stream_putc (s, CAPABILITY_CODE_MP);
                    959:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    960:       stream_putw (s, AFI_IP);
                    961:       stream_putc (s, 0);
                    962:       stream_putc (s, SAFI_MULTICAST);
                    963:     }
                    964:   /* IPv4 VPN */
                    965:   if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
                    966:     {
                    967:       peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
                    968:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    969:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    970:       stream_putc (s, CAPABILITY_CODE_MP);
                    971:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    972:       stream_putw (s, AFI_IP);
                    973:       stream_putc (s, 0);
                    974:       stream_putc (s, BGP_SAFI_VPNV4);
                    975:     }
                    976: #ifdef HAVE_IPV6
                    977:   /* IPv6 unicast. */
                    978:   if (peer->afc[AFI_IP6][SAFI_UNICAST])
                    979:     {
                    980:       peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
                    981:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    982:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    983:       stream_putc (s, CAPABILITY_CODE_MP);
                    984:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    985:       stream_putw (s, AFI_IP6);
                    986:       stream_putc (s, 0);
                    987:       stream_putc (s, SAFI_UNICAST);
                    988:     }
                    989:   /* IPv6 multicast. */
                    990:   if (peer->afc[AFI_IP6][SAFI_MULTICAST])
                    991:     {
                    992:       peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
                    993:       stream_putc (s, BGP_OPEN_OPT_CAP);
                    994:       stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
                    995:       stream_putc (s, CAPABILITY_CODE_MP);
                    996:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
                    997:       stream_putw (s, AFI_IP6);
                    998:       stream_putc (s, 0);
                    999:       stream_putc (s, SAFI_MULTICAST);
                   1000:     }
                   1001: #endif /* HAVE_IPV6 */
                   1002: 
                   1003:   /* Route refresh. */
                   1004:   SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
                   1005:   stream_putc (s, BGP_OPEN_OPT_CAP);
                   1006:   stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
                   1007:   stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
                   1008:   stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
                   1009:   stream_putc (s, BGP_OPEN_OPT_CAP);
                   1010:   stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
                   1011:   stream_putc (s, CAPABILITY_CODE_REFRESH);
                   1012:   stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
                   1013: 
                   1014:   /* AS4 */
                   1015:   SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
                   1016:   stream_putc (s, BGP_OPEN_OPT_CAP);
                   1017:   stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
                   1018:   stream_putc (s, CAPABILITY_CODE_AS4);
                   1019:   stream_putc (s, CAPABILITY_CODE_AS4_LEN);
                   1020:   if ( peer->change_local_as )
                   1021:     local_as = peer->change_local_as;
                   1022:   else
                   1023:     local_as = peer->local_as;
                   1024:   stream_putl (s, local_as );
                   1025: 
                   1026:   /* ORF capability. */
                   1027:   for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
                   1028:     for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
                   1029:       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
                   1030:          || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
                   1031:        {
                   1032:          bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
                   1033:          bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
                   1034:        }
                   1035: 
                   1036:   /* Dynamic capability. */
                   1037:   if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
                   1038:     {
                   1039:       SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
                   1040:       stream_putc (s, BGP_OPEN_OPT_CAP);
                   1041:       stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
                   1042:       stream_putc (s, CAPABILITY_CODE_DYNAMIC);
                   1043:       stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
                   1044:     }
                   1045: 
                   1046:   /* Graceful restart capability */
                   1047:   if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
                   1048:     {
                   1049:       SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
                   1050:       stream_putc (s, BGP_OPEN_OPT_CAP);
                   1051:       stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
                   1052:       stream_putc (s, CAPABILITY_CODE_RESTART);
                   1053:       stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
                   1054:       stream_putw (s, peer->bgp->restart_time);
                   1055:      }
                   1056: 
                   1057:   /* Total Opt Parm Len. */
                   1058:   len = stream_get_endp (s) - cp - 1;
                   1059:   stream_putc_at (s, cp, len);
                   1060: }

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