File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgp_open.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:37 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

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

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