Annotation of embedaddon/quagga/bgpd/bgp_packet.c, revision 1.1

1.1     ! misho       1: /* BGP packet management routine.
        !             2:    Copyright (C) 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 "thread.h"
        !            24: #include "stream.h"
        !            25: #include "network.h"
        !            26: #include "prefix.h"
        !            27: #include "command.h"
        !            28: #include "log.h"
        !            29: #include "memory.h"
        !            30: #include "sockunion.h"         /* for inet_ntop () */
        !            31: #include "linklist.h"
        !            32: #include "plist.h"
        !            33: 
        !            34: #include "bgpd/bgpd.h"
        !            35: #include "bgpd/bgp_table.h"
        !            36: #include "bgpd/bgp_dump.h"
        !            37: #include "bgpd/bgp_attr.h"
        !            38: #include "bgpd/bgp_debug.h"
        !            39: #include "bgpd/bgp_fsm.h"
        !            40: #include "bgpd/bgp_route.h"
        !            41: #include "bgpd/bgp_packet.h"
        !            42: #include "bgpd/bgp_open.h"
        !            43: #include "bgpd/bgp_aspath.h"
        !            44: #include "bgpd/bgp_community.h"
        !            45: #include "bgpd/bgp_ecommunity.h"
        !            46: #include "bgpd/bgp_network.h"
        !            47: #include "bgpd/bgp_mplsvpn.h"
        !            48: #include "bgpd/bgp_advertise.h"
        !            49: #include "bgpd/bgp_vty.h"
        !            50: 
        !            51: int stream_put_prefix (struct stream *, struct prefix *);
        !            52: 
        !            53: /* Set up BGP packet marker and packet type. */
        !            54: static int
        !            55: bgp_packet_set_marker (struct stream *s, u_char type)
        !            56: {
        !            57:   int i;
        !            58: 
        !            59:   /* Fill in marker. */
        !            60:   for (i = 0; i < BGP_MARKER_SIZE; i++)
        !            61:     stream_putc (s, 0xff);
        !            62: 
        !            63:   /* Dummy total length. This field is should be filled in later on. */
        !            64:   stream_putw (s, 0);
        !            65: 
        !            66:   /* BGP packet type. */
        !            67:   stream_putc (s, type);
        !            68: 
        !            69:   /* Return current stream size. */
        !            70:   return stream_get_endp (s);
        !            71: }
        !            72: 
        !            73: /* Set BGP packet header size entry.  If size is zero then use current
        !            74:    stream size. */
        !            75: static int
        !            76: bgp_packet_set_size (struct stream *s)
        !            77: {
        !            78:   int cp;
        !            79: 
        !            80:   /* Preserve current pointer. */
        !            81:   cp = stream_get_endp (s);
        !            82:   stream_putw_at (s, BGP_MARKER_SIZE, cp);
        !            83: 
        !            84:   return cp;
        !            85: }
        !            86: 
        !            87: /* Add new packet to the peer. */
        !            88: static void
        !            89: bgp_packet_add (struct peer *peer, struct stream *s)
        !            90: {
        !            91:   /* Add packet to the end of list. */
        !            92:   stream_fifo_push (peer->obuf, s);
        !            93: }
        !            94: 
        !            95: /* Free first packet. */
        !            96: static void
        !            97: bgp_packet_delete (struct peer *peer)
        !            98: {
        !            99:   stream_free (stream_fifo_pop (peer->obuf));
        !           100: }
        !           101: 
        !           102: /* Check file descriptor whether connect is established. */
        !           103: static void
        !           104: bgp_connect_check (struct peer *peer)
        !           105: {
        !           106:   int status;
        !           107:   socklen_t slen;
        !           108:   int ret;
        !           109: 
        !           110:   /* Anyway I have to reset read and write thread. */
        !           111:   BGP_READ_OFF (peer->t_read);
        !           112:   BGP_WRITE_OFF (peer->t_write);
        !           113: 
        !           114:   /* Check file descriptor. */
        !           115:   slen = sizeof (status);
        !           116:   ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
        !           117: 
        !           118:   /* If getsockopt is fail, this is fatal error. */
        !           119:   if (ret < 0)
        !           120:     {
        !           121:       zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
        !           122:       BGP_EVENT_ADD (peer, TCP_fatal_error);
        !           123:       return;
        !           124:     }      
        !           125: 
        !           126:   /* When status is 0 then TCP connection is established. */
        !           127:   if (status == 0)
        !           128:     {
        !           129:       BGP_EVENT_ADD (peer, TCP_connection_open);
        !           130:     }
        !           131:   else
        !           132:     {
        !           133:       if (BGP_DEBUG (events, EVENTS))
        !           134:          plog_debug (peer->log, "%s [Event] Connect failed (%s)",
        !           135:                     peer->host, safe_strerror (errno));
        !           136:       BGP_EVENT_ADD (peer, TCP_connection_open_failed);
        !           137:     }
        !           138: }
        !           139: 
        !           140: /* Make BGP update packet.  */
        !           141: static struct stream *
        !           142: bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
        !           143: {
        !           144:   struct stream *s;
        !           145:   struct bgp_adj_out *adj;
        !           146:   struct bgp_advertise *adv;
        !           147:   struct stream *packet;
        !           148:   struct bgp_node *rn = NULL;
        !           149:   struct bgp_info *binfo = NULL;
        !           150:   bgp_size_t total_attr_len = 0;
        !           151:   unsigned long pos;
        !           152:   char buf[BUFSIZ];
        !           153: 
        !           154:   s = peer->work;
        !           155:   stream_reset (s);
        !           156: 
        !           157:   adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
        !           158: 
        !           159:   while (adv)
        !           160:     {
        !           161:       assert (adv->rn);
        !           162:       rn = adv->rn;
        !           163:       adj = adv->adj;
        !           164:       if (adv->binfo)
        !           165:         binfo = adv->binfo;
        !           166: 
        !           167:       /* When remaining space can't include NLRI and it's length.  */
        !           168:       if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen))
        !           169:        break;
        !           170: 
        !           171:       /* If packet is empty, set attribute. */
        !           172:       if (stream_empty (s))
        !           173:        {
        !           174:          struct prefix_rd *prd = NULL;
        !           175:          u_char *tag = NULL;
        !           176:          struct peer *from = NULL;
        !           177:          
        !           178:          if (rn->prn)
        !           179:            prd = (struct prefix_rd *) &rn->prn->p;
        !           180:           if (binfo)
        !           181:             {
        !           182:               from = binfo->peer;
        !           183:               if (binfo->extra)
        !           184:                 tag = binfo->extra->tag;
        !           185:             }
        !           186:           
        !           187:          bgp_packet_set_marker (s, BGP_MSG_UPDATE);
        !           188:          stream_putw (s, 0);           
        !           189:          pos = stream_get_endp (s);
        !           190:          stream_putw (s, 0);
        !           191:          total_attr_len = bgp_packet_attribute (NULL, peer, s, 
        !           192:                                                 adv->baa->attr,
        !           193:                                                 &rn->p, afi, safi, 
        !           194:                                                 from, prd, tag);
        !           195:          stream_putw_at (s, pos, total_attr_len);
        !           196:        }
        !           197: 
        !           198:       if (afi == AFI_IP && safi == SAFI_UNICAST)
        !           199:        stream_put_prefix (s, &rn->p);
        !           200:       
        !           201:       if (BGP_DEBUG (update, UPDATE_OUT))
        !           202:        zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
        !           203:              peer->host,
        !           204:              inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
        !           205:              rn->p.prefixlen);
        !           206: 
        !           207:       /* Synchnorize attribute.  */
        !           208:       if (adj->attr)
        !           209:        bgp_attr_unintern (&adj->attr);
        !           210:       else
        !           211:        peer->scount[afi][safi]++;
        !           212: 
        !           213:       adj->attr = bgp_attr_intern (adv->baa->attr);
        !           214: 
        !           215:       adv = bgp_advertise_clean (peer, adj, afi, safi);
        !           216: 
        !           217:       if (! (afi == AFI_IP && safi == SAFI_UNICAST))
        !           218:        break;
        !           219:     }
        !           220:         
        !           221:   if (! stream_empty (s))
        !           222:     {
        !           223:       bgp_packet_set_size (s);
        !           224:       packet = stream_dup (s);
        !           225:       bgp_packet_add (peer, packet);
        !           226:       BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
        !           227:       stream_reset (s);
        !           228:       return packet;
        !           229:     }
        !           230:   return NULL;
        !           231: }
        !           232: 
        !           233: static struct stream *
        !           234: bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
        !           235: {
        !           236:   struct stream *s;
        !           237:   struct stream *packet;
        !           238: 
        !           239:   if (DISABLE_BGP_ANNOUNCE)
        !           240:     return NULL;
        !           241: 
        !           242:   if (BGP_DEBUG (normal, NORMAL))
        !           243:     zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
        !           244: 
        !           245:   s = stream_new (BGP_MAX_PACKET_SIZE);
        !           246: 
        !           247:   /* Make BGP update packet. */
        !           248:   bgp_packet_set_marker (s, BGP_MSG_UPDATE);
        !           249: 
        !           250:   /* Unfeasible Routes Length */
        !           251:   stream_putw (s, 0);
        !           252: 
        !           253:   if (afi == AFI_IP && safi == SAFI_UNICAST)
        !           254:     {
        !           255:       /* Total Path Attribute Length */
        !           256:       stream_putw (s, 0);
        !           257:     }
        !           258:   else
        !           259:     {
        !           260:       /* Total Path Attribute Length */
        !           261:       stream_putw (s, 6);
        !           262:       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
        !           263:       stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
        !           264:       stream_putc (s, 3);
        !           265:       stream_putw (s, afi);
        !           266:       stream_putc (s, safi);
        !           267:     }
        !           268: 
        !           269:   bgp_packet_set_size (s);
        !           270:   packet = stream_dup (s);
        !           271:   bgp_packet_add (peer, packet);
        !           272:   stream_free (s);
        !           273:   return packet;
        !           274: }
        !           275: 
        !           276: /* Make BGP withdraw packet.  */
        !           277: static struct stream *
        !           278: bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
        !           279: {
        !           280:   struct stream *s;
        !           281:   struct stream *packet;
        !           282:   struct bgp_adj_out *adj;
        !           283:   struct bgp_advertise *adv;
        !           284:   struct bgp_node *rn;
        !           285:   unsigned long pos;
        !           286:   bgp_size_t unfeasible_len;
        !           287:   bgp_size_t total_attr_len;
        !           288:   char buf[BUFSIZ];
        !           289: 
        !           290:   s = peer->work;
        !           291:   stream_reset (s);
        !           292: 
        !           293:   while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
        !           294:     {
        !           295:       assert (adv->rn);
        !           296:       adj = adv->adj;
        !           297:       rn = adv->rn;
        !           298: 
        !           299:       if (STREAM_REMAIN (s) 
        !           300:          < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
        !           301:        break;
        !           302: 
        !           303:       if (stream_empty (s))
        !           304:        {
        !           305:          bgp_packet_set_marker (s, BGP_MSG_UPDATE);
        !           306:          stream_putw (s, 0);
        !           307:        }
        !           308: 
        !           309:       if (afi == AFI_IP && safi == SAFI_UNICAST)
        !           310:        stream_put_prefix (s, &rn->p);
        !           311:       else
        !           312:        {
        !           313:          struct prefix_rd *prd = NULL;
        !           314:          
        !           315:          if (rn->prn)
        !           316:            prd = (struct prefix_rd *) &rn->prn->p;
        !           317:          pos = stream_get_endp (s);
        !           318:          stream_putw (s, 0);
        !           319:          total_attr_len
        !           320:            = bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL);
        !           321:       
        !           322:          /* Set total path attribute length. */
        !           323:          stream_putw_at (s, pos, total_attr_len);
        !           324:        }
        !           325: 
        !           326:       if (BGP_DEBUG (update, UPDATE_OUT))
        !           327:        zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
        !           328:              peer->host,
        !           329:              inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, BUFSIZ),
        !           330:              rn->p.prefixlen);
        !           331: 
        !           332:       peer->scount[afi][safi]--;
        !           333: 
        !           334:       bgp_adj_out_remove (rn, adj, peer, afi, safi);
        !           335:       bgp_unlock_node (rn);
        !           336: 
        !           337:       if (! (afi == AFI_IP && safi == SAFI_UNICAST))
        !           338:        break;
        !           339:     }
        !           340: 
        !           341:   if (! stream_empty (s))
        !           342:     {
        !           343:       if (afi == AFI_IP && safi == SAFI_UNICAST)
        !           344:        {
        !           345:          unfeasible_len 
        !           346:            = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
        !           347:          stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
        !           348:          stream_putw (s, 0);
        !           349:        }
        !           350:       bgp_packet_set_size (s);
        !           351:       packet = stream_dup (s);
        !           352:       bgp_packet_add (peer, packet);
        !           353:       stream_reset (s);
        !           354:       return packet;
        !           355:     }
        !           356: 
        !           357:   return NULL;
        !           358: }
        !           359: 
        !           360: void
        !           361: bgp_default_update_send (struct peer *peer, struct attr *attr,
        !           362:                         afi_t afi, safi_t safi, struct peer *from)
        !           363: {
        !           364:   struct stream *s;
        !           365:   struct stream *packet;
        !           366:   struct prefix p;
        !           367:   unsigned long pos;
        !           368:   bgp_size_t total_attr_len;
        !           369:   char attrstr[BUFSIZ];
        !           370:   char buf[BUFSIZ];
        !           371: 
        !           372:   if (DISABLE_BGP_ANNOUNCE)
        !           373:     return;
        !           374: 
        !           375:   if (afi == AFI_IP)
        !           376:     str2prefix ("0.0.0.0/0", &p);
        !           377: #ifdef HAVE_IPV6
        !           378:   else 
        !           379:     str2prefix ("::/0", &p);
        !           380: #endif /* HAVE_IPV6 */
        !           381: 
        !           382:   /* Logging the attribute. */
        !           383:   if (BGP_DEBUG (update, UPDATE_OUT))
        !           384:     {
        !           385:       bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
        !           386:       zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
        !           387:            peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
        !           388:            p.prefixlen, attrstr);
        !           389:     }
        !           390: 
        !           391:   s = stream_new (BGP_MAX_PACKET_SIZE);
        !           392: 
        !           393:   /* Make BGP update packet. */
        !           394:   bgp_packet_set_marker (s, BGP_MSG_UPDATE);
        !           395: 
        !           396:   /* Unfeasible Routes Length. */
        !           397:   stream_putw (s, 0);
        !           398: 
        !           399:   /* Make place for total attribute length.  */
        !           400:   pos = stream_get_endp (s);
        !           401:   stream_putw (s, 0);
        !           402:   total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
        !           403: 
        !           404:   /* Set Total Path Attribute Length. */
        !           405:   stream_putw_at (s, pos, total_attr_len);
        !           406: 
        !           407:   /* NLRI set. */
        !           408:   if (p.family == AF_INET && safi == SAFI_UNICAST)
        !           409:     stream_put_prefix (s, &p);
        !           410: 
        !           411:   /* Set size. */
        !           412:   bgp_packet_set_size (s);
        !           413: 
        !           414:   packet = stream_dup (s);
        !           415:   stream_free (s);
        !           416: 
        !           417:   /* Dump packet if debug option is set. */
        !           418: #ifdef DEBUG
        !           419:   /* bgp_packet_dump (packet); */
        !           420: #endif /* DEBUG */
        !           421: 
        !           422:   /* Add packet to the peer. */
        !           423:   bgp_packet_add (peer, packet);
        !           424: 
        !           425:   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
        !           426: }
        !           427: 
        !           428: void
        !           429: bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
        !           430: {
        !           431:   struct stream *s;
        !           432:   struct stream *packet;
        !           433:   struct prefix p;
        !           434:   unsigned long pos;
        !           435:   unsigned long cp;
        !           436:   bgp_size_t unfeasible_len;
        !           437:   bgp_size_t total_attr_len;
        !           438:   char buf[BUFSIZ];
        !           439: 
        !           440:   if (DISABLE_BGP_ANNOUNCE)
        !           441:     return;
        !           442: 
        !           443:   if (afi == AFI_IP)
        !           444:     str2prefix ("0.0.0.0/0", &p);
        !           445: #ifdef HAVE_IPV6
        !           446:   else 
        !           447:     str2prefix ("::/0", &p);
        !           448: #endif /* HAVE_IPV6 */
        !           449: 
        !           450:   total_attr_len = 0;
        !           451:   pos = 0;
        !           452: 
        !           453:   if (BGP_DEBUG (update, UPDATE_OUT))
        !           454:     zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
        !           455:           peer->host, inet_ntop(p.family, &(p.u.prefix), buf, BUFSIZ),
        !           456:           p.prefixlen);
        !           457: 
        !           458:   s = stream_new (BGP_MAX_PACKET_SIZE);
        !           459: 
        !           460:   /* Make BGP update packet. */
        !           461:   bgp_packet_set_marker (s, BGP_MSG_UPDATE);
        !           462: 
        !           463:   /* Unfeasible Routes Length. */;
        !           464:   cp = stream_get_endp (s);
        !           465:   stream_putw (s, 0);
        !           466: 
        !           467:   /* Withdrawn Routes. */
        !           468:   if (p.family == AF_INET && safi == SAFI_UNICAST)
        !           469:     {
        !           470:       stream_put_prefix (s, &p);
        !           471: 
        !           472:       unfeasible_len = stream_get_endp (s) - cp - 2;
        !           473: 
        !           474:       /* Set unfeasible len.  */
        !           475:       stream_putw_at (s, cp, unfeasible_len);
        !           476: 
        !           477:       /* Set total path attribute length. */
        !           478:       stream_putw (s, 0);
        !           479:     }
        !           480:   else
        !           481:     {
        !           482:       pos = stream_get_endp (s);
        !           483:       stream_putw (s, 0);
        !           484:       total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL);
        !           485: 
        !           486:       /* Set total path attribute length. */
        !           487:       stream_putw_at (s, pos, total_attr_len);
        !           488:     }
        !           489: 
        !           490:   bgp_packet_set_size (s);
        !           491: 
        !           492:   packet = stream_dup (s);
        !           493:   stream_free (s);
        !           494: 
        !           495:   /* Add packet to the peer. */
        !           496:   bgp_packet_add (peer, packet);
        !           497: 
        !           498:   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
        !           499: }
        !           500: 
        !           501: /* Get next packet to be written.  */
        !           502: static struct stream *
        !           503: bgp_write_packet (struct peer *peer)
        !           504: {
        !           505:   afi_t afi;
        !           506:   safi_t safi;
        !           507:   struct stream *s = NULL;
        !           508:   struct bgp_advertise *adv;
        !           509: 
        !           510:   s = stream_fifo_head (peer->obuf);
        !           511:   if (s)
        !           512:     return s;
        !           513: 
        !           514:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
        !           515:     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
        !           516:       {
        !           517:        adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
        !           518:        if (adv)
        !           519:          {
        !           520:            s = bgp_withdraw_packet (peer, afi, safi);
        !           521:            if (s)
        !           522:              return s;
        !           523:          }
        !           524:       }
        !           525:     
        !           526:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
        !           527:     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
        !           528:       {
        !           529:        adv = FIFO_HEAD (&peer->sync[afi][safi]->update);
        !           530:        if (adv)
        !           531:          {
        !           532:             if (adv->binfo && adv->binfo->uptime < peer->synctime)
        !           533:              {
        !           534:                if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
        !           535:                    && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
        !           536:                    && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
        !           537:                    && safi != SAFI_MPLS_VPN)
        !           538:                  {
        !           539:                    if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
        !           540:                        PEER_STATUS_EOR_RECEIVED))
        !           541:                      s = bgp_update_packet (peer, afi, safi);
        !           542:                  }
        !           543:                else
        !           544:                  s = bgp_update_packet (peer, afi, safi);
        !           545:              }
        !           546: 
        !           547:            if (s)
        !           548:              return s;
        !           549:          }
        !           550: 
        !           551:        if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
        !           552:          {
        !           553:            if (peer->afc_nego[afi][safi] && peer->synctime
        !           554:                && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
        !           555:                && safi != SAFI_MPLS_VPN)
        !           556:              {
        !           557:                SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
        !           558:                return bgp_update_packet_eor (peer, afi, safi);
        !           559:              }
        !           560:          }
        !           561:       }
        !           562: 
        !           563:   return NULL;
        !           564: }
        !           565: 
        !           566: /* Is there partially written packet or updates we can send right
        !           567:    now.  */
        !           568: static int
        !           569: bgp_write_proceed (struct peer *peer)
        !           570: {
        !           571:   afi_t afi;
        !           572:   safi_t safi;
        !           573:   struct bgp_advertise *adv;
        !           574: 
        !           575:   if (stream_fifo_head (peer->obuf))
        !           576:     return 1;
        !           577: 
        !           578:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
        !           579:     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
        !           580:       if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
        !           581:        return 1;
        !           582: 
        !           583:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
        !           584:     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
        !           585:       if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
        !           586:        if (adv->binfo->uptime < peer->synctime)
        !           587:          return 1;
        !           588: 
        !           589:   return 0;
        !           590: }
        !           591: 
        !           592: /* Write packet to the peer. */
        !           593: int
        !           594: bgp_write (struct thread *thread)
        !           595: {
        !           596:   struct peer *peer;
        !           597:   u_char type;
        !           598:   struct stream *s; 
        !           599:   int num;
        !           600:   unsigned int count = 0;
        !           601: 
        !           602:   /* Yes first of all get peer pointer. */
        !           603:   peer = THREAD_ARG (thread);
        !           604:   peer->t_write = NULL;
        !           605: 
        !           606:   /* For non-blocking IO check. */
        !           607:   if (peer->status == Connect)
        !           608:     {
        !           609:       bgp_connect_check (peer);
        !           610:       return 0;
        !           611:     }
        !           612: 
        !           613:   s = bgp_write_packet (peer);
        !           614:   if (!s)
        !           615:     return 0;  /* nothing to send */
        !           616: 
        !           617:   sockopt_cork (peer->fd, 1);
        !           618: 
        !           619:   /* Nonblocking write until TCP output buffer is full.  */
        !           620:   do
        !           621:     {
        !           622:       int writenum;
        !           623: 
        !           624:       /* Number of bytes to be sent.  */
        !           625:       writenum = stream_get_endp (s) - stream_get_getp (s);
        !           626: 
        !           627:       /* Call write() system call.  */
        !           628:       num = write (peer->fd, STREAM_PNT (s), writenum);
        !           629:       if (num < 0)
        !           630:        {
        !           631:          /* write failed either retry needed or error */
        !           632:          if (ERRNO_IO_RETRY(errno))
        !           633:                break;
        !           634: 
        !           635:           BGP_EVENT_ADD (peer, TCP_fatal_error);
        !           636:          return 0;
        !           637:        }
        !           638: 
        !           639:       if (num != writenum)
        !           640:        {
        !           641:          /* Partial write */
        !           642:          stream_forward_getp (s, num);
        !           643:          break;
        !           644:        }
        !           645: 
        !           646:       /* Retrieve BGP packet type. */
        !           647:       stream_set_getp (s, BGP_MARKER_SIZE + 2);
        !           648:       type = stream_getc (s);
        !           649: 
        !           650:       switch (type)
        !           651:        {
        !           652:        case BGP_MSG_OPEN:
        !           653:          peer->open_out++;
        !           654:          break;
        !           655:        case BGP_MSG_UPDATE:
        !           656:          peer->update_out++;
        !           657:          break;
        !           658:        case BGP_MSG_NOTIFY:
        !           659:          peer->notify_out++;
        !           660:          /* Double start timer. */
        !           661:          peer->v_start *= 2;
        !           662: 
        !           663:          /* Overflow check. */
        !           664:          if (peer->v_start >= (60 * 2))
        !           665:            peer->v_start = (60 * 2);
        !           666: 
        !           667:          /* Flush any existing events */
        !           668:          BGP_EVENT_ADD (peer, BGP_Stop);
        !           669:          return 0;
        !           670:        case BGP_MSG_KEEPALIVE:
        !           671:          peer->keepalive_out++;
        !           672:          break;
        !           673:        case BGP_MSG_ROUTE_REFRESH_NEW:
        !           674:        case BGP_MSG_ROUTE_REFRESH_OLD:
        !           675:          peer->refresh_out++;
        !           676:          break;
        !           677:        case BGP_MSG_CAPABILITY:
        !           678:          peer->dynamic_cap_out++;
        !           679:          break;
        !           680:        }
        !           681: 
        !           682:       /* OK we send packet so delete it. */
        !           683:       bgp_packet_delete (peer);
        !           684:     }
        !           685:   while (++count < BGP_WRITE_PACKET_MAX &&
        !           686:         (s = bgp_write_packet (peer)) != NULL);
        !           687:   
        !           688:   if (bgp_write_proceed (peer))
        !           689:     BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
        !           690:   else
        !           691:     sockopt_cork (peer->fd, 0);
        !           692:   
        !           693:   return 0;
        !           694: }
        !           695: 
        !           696: /* This is only for sending NOTIFICATION message to neighbor. */
        !           697: static int
        !           698: bgp_write_notify (struct peer *peer)
        !           699: {
        !           700:   int ret, val;
        !           701:   u_char type;
        !           702:   struct stream *s; 
        !           703: 
        !           704:   /* There should be at least one packet. */
        !           705:   s = stream_fifo_head (peer->obuf);
        !           706:   if (!s)
        !           707:     return 0;
        !           708:   assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
        !           709: 
        !           710:   /* Put socket in blocking mode. */
        !           711:   val = fcntl (peer->fd, F_GETFL, 0);
        !           712:   fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK);
        !           713: 
        !           714:   ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s));
        !           715:   if (ret <= 0)
        !           716:     {
        !           717:       BGP_EVENT_ADD (peer, TCP_fatal_error);
        !           718:       return 0;
        !           719:     }
        !           720: 
        !           721:   /* Retrieve BGP packet type. */
        !           722:   stream_set_getp (s, BGP_MARKER_SIZE + 2);
        !           723:   type = stream_getc (s);
        !           724: 
        !           725:   assert (type == BGP_MSG_NOTIFY);
        !           726: 
        !           727:   /* Type should be notify. */
        !           728:   peer->notify_out++;
        !           729: 
        !           730:   /* Double start timer. */
        !           731:   peer->v_start *= 2;
        !           732: 
        !           733:   /* Overflow check. */
        !           734:   if (peer->v_start >= (60 * 2))
        !           735:     peer->v_start = (60 * 2);
        !           736: 
        !           737:   BGP_EVENT_ADD (peer, BGP_Stop);
        !           738: 
        !           739:   return 0;
        !           740: }
        !           741: 
        !           742: /* Make keepalive packet and send it to the peer. */
        !           743: void
        !           744: bgp_keepalive_send (struct peer *peer)
        !           745: {
        !           746:   struct stream *s;
        !           747:   int length;
        !           748: 
        !           749:   s = stream_new (BGP_MAX_PACKET_SIZE);
        !           750: 
        !           751:   /* Make keepalive packet. */
        !           752:   bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
        !           753: 
        !           754:   /* Set packet size. */
        !           755:   length = bgp_packet_set_size (s);
        !           756: 
        !           757:   /* Dump packet if debug option is set. */
        !           758:   /* bgp_packet_dump (s); */
        !           759:  
        !           760:   if (BGP_DEBUG (keepalive, KEEPALIVE))  
        !           761:     zlog_debug ("%s sending KEEPALIVE", peer->host); 
        !           762:   if (BGP_DEBUG (normal, NORMAL))
        !           763:     zlog_debug ("%s send message type %d, length (incl. header) %d",
        !           764:                peer->host, BGP_MSG_KEEPALIVE, length);
        !           765: 
        !           766:   /* Add packet to the peer. */
        !           767:   bgp_packet_add (peer, s);
        !           768: 
        !           769:   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
        !           770: }
        !           771: 
        !           772: /* Make open packet and send it to the peer. */
        !           773: void
        !           774: bgp_open_send (struct peer *peer)
        !           775: {
        !           776:   struct stream *s;
        !           777:   int length;
        !           778:   u_int16_t send_holdtime;
        !           779:   as_t local_as;
        !           780: 
        !           781:   if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
        !           782:     send_holdtime = peer->holdtime;
        !           783:   else
        !           784:     send_holdtime = peer->bgp->default_holdtime;
        !           785: 
        !           786:   /* local-as Change */
        !           787:   if (peer->change_local_as)
        !           788:     local_as = peer->change_local_as; 
        !           789:   else
        !           790:     local_as = peer->local_as; 
        !           791: 
        !           792:   s = stream_new (BGP_MAX_PACKET_SIZE);
        !           793: 
        !           794:   /* Make open packet. */
        !           795:   bgp_packet_set_marker (s, BGP_MSG_OPEN);
        !           796: 
        !           797:   /* Set open packet values. */
        !           798:   stream_putc (s, BGP_VERSION_4);        /* BGP version */
        !           799:   stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as 
        !           800:                                            : BGP_AS_TRANS);
        !           801:   stream_putw (s, send_holdtime);       /* Hold Time */
        !           802:   stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
        !           803: 
        !           804:   /* Set capability code. */
        !           805:   bgp_open_capability (s, peer);
        !           806: 
        !           807:   /* Set BGP packet length. */
        !           808:   length = bgp_packet_set_size (s);
        !           809: 
        !           810:   if (BGP_DEBUG (normal, NORMAL))
        !           811:     zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s", 
        !           812:               peer->host, BGP_VERSION_4, local_as,
        !           813:               send_holdtime, inet_ntoa (peer->local_id));
        !           814: 
        !           815:   if (BGP_DEBUG (normal, NORMAL))
        !           816:     zlog_debug ("%s send message type %d, length (incl. header) %d",
        !           817:               peer->host, BGP_MSG_OPEN, length);
        !           818: 
        !           819:   /* Dump packet if debug option is set. */
        !           820:   /* bgp_packet_dump (s); */
        !           821: 
        !           822:   /* Add packet to the peer. */
        !           823:   bgp_packet_add (peer, s);
        !           824: 
        !           825:   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
        !           826: }
        !           827: 
        !           828: /* Send BGP notify packet with data potion. */
        !           829: void
        !           830: bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
        !           831:                           u_char *data, size_t datalen)
        !           832: {
        !           833:   struct stream *s;
        !           834:   int length;
        !           835: 
        !           836:   /* Allocate new stream. */
        !           837:   s = stream_new (BGP_MAX_PACKET_SIZE);
        !           838: 
        !           839:   /* Make nitify packet. */
        !           840:   bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
        !           841: 
        !           842:   /* Set notify packet values. */
        !           843:   stream_putc (s, code);        /* BGP notify code */
        !           844:   stream_putc (s, sub_code);   /* BGP notify sub_code */
        !           845: 
        !           846:   /* If notify data is present. */
        !           847:   if (data)
        !           848:     stream_write (s, data, datalen);
        !           849:   
        !           850:   /* Set BGP packet length. */
        !           851:   length = bgp_packet_set_size (s);
        !           852:   
        !           853:   /* Add packet to the peer. */
        !           854:   stream_fifo_clean (peer->obuf);
        !           855:   bgp_packet_add (peer, s);
        !           856: 
        !           857:   /* For debug */
        !           858:   {
        !           859:     struct bgp_notify bgp_notify;
        !           860:     int first = 0;
        !           861:     int i;
        !           862:     char c[4];
        !           863: 
        !           864:     bgp_notify.code = code;
        !           865:     bgp_notify.subcode = sub_code;
        !           866:     bgp_notify.data = NULL;
        !           867:     bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
        !           868:     
        !           869:     if (bgp_notify.length)
        !           870:       {
        !           871:        bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
        !           872:        for (i = 0; i < bgp_notify.length; i++)
        !           873:          if (first)
        !           874:            {
        !           875:              sprintf (c, " %02x", data[i]);
        !           876:              strcat (bgp_notify.data, c);
        !           877:            }
        !           878:          else
        !           879:            {
        !           880:              first = 1;
        !           881:              sprintf (c, "%02x", data[i]);
        !           882:              strcpy (bgp_notify.data, c);
        !           883:            }
        !           884:       }
        !           885:     bgp_notify_print (peer, &bgp_notify, "sending");
        !           886:     if (bgp_notify.data)
        !           887:       XFREE (MTYPE_TMP, bgp_notify.data);
        !           888:   }
        !           889: 
        !           890:   if (BGP_DEBUG (normal, NORMAL))
        !           891:     zlog_debug ("%s send message type %d, length (incl. header) %d",
        !           892:               peer->host, BGP_MSG_NOTIFY, length);
        !           893: 
        !           894:   /* peer reset cause */
        !           895:   if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
        !           896:     {
        !           897:       if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
        !           898:       {
        !           899:         peer->last_reset = PEER_DOWN_USER_RESET;
        !           900:         zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
        !           901:       }
        !           902:       else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
        !           903:       {
        !           904:         peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
        !           905:         zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
        !           906:       }
        !           907:       else
        !           908:       {
        !           909:         peer->last_reset = PEER_DOWN_NOTIFY_SEND;
        !           910:         zlog_info ("Notification sent to neighbor %s: type %u/%u",
        !           911:                    peer->host, code, sub_code);
        !           912:       }
        !           913:     }
        !           914:   else
        !           915:      zlog_info ("Notification sent to neighbor %s: configuration change",
        !           916:                 peer->host);
        !           917: 
        !           918:   /* Call immediately. */
        !           919:   BGP_WRITE_OFF (peer->t_write);
        !           920: 
        !           921:   bgp_write_notify (peer);
        !           922: }
        !           923: 
        !           924: /* Send BGP notify packet. */
        !           925: void
        !           926: bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
        !           927: {
        !           928:   bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
        !           929: }
        !           930: 
        !           931: /* Send route refresh message to the peer. */
        !           932: void
        !           933: bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
        !           934:                        u_char orf_type, u_char when_to_refresh, int remove)
        !           935: {
        !           936:   struct stream *s;
        !           937:   struct stream *packet;
        !           938:   int length;
        !           939:   struct bgp_filter *filter;
        !           940:   int orf_refresh = 0;
        !           941: 
        !           942:   if (DISABLE_BGP_ANNOUNCE)
        !           943:     return;
        !           944: 
        !           945:   filter = &peer->filter[afi][safi];
        !           946: 
        !           947:   /* Adjust safi code. */
        !           948:   if (safi == SAFI_MPLS_VPN)
        !           949:     safi = BGP_SAFI_VPNV4;
        !           950:   
        !           951:   s = stream_new (BGP_MAX_PACKET_SIZE);
        !           952: 
        !           953:   /* Make BGP update packet. */
        !           954:   if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
        !           955:     bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
        !           956:   else
        !           957:     bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
        !           958: 
        !           959:   /* Encode Route Refresh message. */
        !           960:   stream_putw (s, afi);
        !           961:   stream_putc (s, 0);
        !           962:   stream_putc (s, safi);
        !           963:  
        !           964:   if (orf_type == ORF_TYPE_PREFIX
        !           965:       || orf_type == ORF_TYPE_PREFIX_OLD)
        !           966:     if (remove || filter->plist[FILTER_IN].plist)
        !           967:       {
        !           968:        u_int16_t orf_len;
        !           969:        unsigned long orfp;
        !           970: 
        !           971:        orf_refresh = 1; 
        !           972:        stream_putc (s, when_to_refresh);
        !           973:        stream_putc (s, orf_type);
        !           974:        orfp = stream_get_endp (s);
        !           975:        stream_putw (s, 0);
        !           976: 
        !           977:        if (remove)
        !           978:          {
        !           979:            UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
        !           980:            stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
        !           981:            if (BGP_DEBUG (normal, NORMAL))
        !           982:              zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d", 
        !           983:                         peer->host, orf_type,
        !           984:                         (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
        !           985:                         afi, safi);
        !           986:          }
        !           987:        else
        !           988:          {
        !           989:            SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
        !           990:            prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
        !           991:                                  ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
        !           992:                                  ORF_COMMON_PART_DENY);
        !           993:            if (BGP_DEBUG (normal, NORMAL))
        !           994:              zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d", 
        !           995:                         peer->host, orf_type,
        !           996:                         (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
        !           997:                         afi, safi);
        !           998:          }
        !           999: 
        !          1000:        /* Total ORF Entry Len. */
        !          1001:        orf_len = stream_get_endp (s) - orfp - 2;
        !          1002:        stream_putw_at (s, orfp, orf_len);
        !          1003:       }
        !          1004: 
        !          1005:   /* Set packet size. */
        !          1006:   length = bgp_packet_set_size (s);
        !          1007: 
        !          1008:   if (BGP_DEBUG (normal, NORMAL))
        !          1009:     {
        !          1010:       if (! orf_refresh)
        !          1011:        zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d", 
        !          1012:                   peer->host, afi, safi);
        !          1013:       zlog_debug ("%s send message type %d, length (incl. header) %d",
        !          1014:                 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
        !          1015:                 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
        !          1016:     }
        !          1017: 
        !          1018:   /* Make real packet. */
        !          1019:   packet = stream_dup (s);
        !          1020:   stream_free (s);
        !          1021: 
        !          1022:   /* Add packet to the peer. */
        !          1023:   bgp_packet_add (peer, packet);
        !          1024: 
        !          1025:   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
        !          1026: }
        !          1027: 
        !          1028: /* Send capability message to the peer. */
        !          1029: void
        !          1030: bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
        !          1031:                     int capability_code, int action)
        !          1032: {
        !          1033:   struct stream *s;
        !          1034:   struct stream *packet;
        !          1035:   int length;
        !          1036: 
        !          1037:   /* Adjust safi code. */
        !          1038:   if (safi == SAFI_MPLS_VPN)
        !          1039:     safi = BGP_SAFI_VPNV4;
        !          1040: 
        !          1041:   s = stream_new (BGP_MAX_PACKET_SIZE);
        !          1042: 
        !          1043:   /* Make BGP update packet. */
        !          1044:   bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
        !          1045: 
        !          1046:   /* Encode MP_EXT capability. */
        !          1047:   if (capability_code == CAPABILITY_CODE_MP)
        !          1048:     {
        !          1049:       stream_putc (s, action);
        !          1050:       stream_putc (s, CAPABILITY_CODE_MP);
        !          1051:       stream_putc (s, CAPABILITY_CODE_MP_LEN);
        !          1052:       stream_putw (s, afi);
        !          1053:       stream_putc (s, 0);
        !          1054:       stream_putc (s, safi);
        !          1055: 
        !          1056:       if (BGP_DEBUG (normal, NORMAL))
        !          1057:         zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
        !          1058:                   peer->host, action == CAPABILITY_ACTION_SET ?
        !          1059:                   "Advertising" : "Removing", afi, safi);
        !          1060:     }
        !          1061: 
        !          1062:   /* Set packet size. */
        !          1063:   length = bgp_packet_set_size (s);
        !          1064: 
        !          1065:   /* Make real packet. */
        !          1066:   packet = stream_dup (s);
        !          1067:   stream_free (s);
        !          1068: 
        !          1069:   /* Add packet to the peer. */
        !          1070:   bgp_packet_add (peer, packet);
        !          1071: 
        !          1072:   if (BGP_DEBUG (normal, NORMAL))
        !          1073:     zlog_debug ("%s send message type %d, length (incl. header) %d",
        !          1074:               peer->host, BGP_MSG_CAPABILITY, length);
        !          1075: 
        !          1076:   BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
        !          1077: }
        !          1078: 
        !          1079: /* RFC1771 6.8 Connection collision detection. */
        !          1080: static int
        !          1081: bgp_collision_detect (struct peer *new, struct in_addr remote_id)
        !          1082: {
        !          1083:   struct peer *peer;
        !          1084:   struct listnode *node, *nnode;
        !          1085:   struct bgp *bgp;
        !          1086: 
        !          1087:   bgp = bgp_get_default ();
        !          1088:   if (! bgp)
        !          1089:     return 0;
        !          1090:   
        !          1091:   /* Upon receipt of an OPEN message, the local system must examine
        !          1092:      all of its connections that are in the OpenConfirm state.  A BGP
        !          1093:      speaker may also examine connections in an OpenSent state if it
        !          1094:      knows the BGP Identifier of the peer by means outside of the
        !          1095:      protocol.  If among these connections there is a connection to a
        !          1096:      remote BGP speaker whose BGP Identifier equals the one in the
        !          1097:      OPEN message, then the local system performs the following
        !          1098:      collision resolution procedure: */
        !          1099: 
        !          1100:   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
        !          1101:     {
        !          1102:       /* Under OpenConfirm status, local peer structure already hold
        !          1103:          remote router ID. */
        !          1104: 
        !          1105:       if (peer != new
        !          1106:          && (peer->status == OpenConfirm || peer->status == OpenSent)
        !          1107:          && sockunion_same (&peer->su, &new->su))
        !          1108:        {
        !          1109:          /* 1. The BGP Identifier of the local system is compared to
        !          1110:             the BGP Identifier of the remote system (as specified in
        !          1111:             the OPEN message). */
        !          1112: 
        !          1113:          if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
        !          1114:            {
        !          1115:              /* 2. If the value of the local BGP Identifier is less
        !          1116:                 than the remote one, the local system closes BGP
        !          1117:                 connection that already exists (the one that is
        !          1118:                 already in the OpenConfirm state), and accepts BGP
        !          1119:                 connection initiated by the remote system. */
        !          1120: 
        !          1121:              if (peer->fd >= 0)
        !          1122:                bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
        !          1123:              return 1;
        !          1124:            }
        !          1125:          else
        !          1126:            {
        !          1127:              /* 3. Otherwise, the local system closes newly created
        !          1128:                 BGP connection (the one associated with the newly
        !          1129:                 received OPEN message), and continues to use the
        !          1130:                 existing one (the one that is already in the
        !          1131:                 OpenConfirm state). */
        !          1132: 
        !          1133:              if (new->fd >= 0)
        !          1134:                bgp_notify_send (new, BGP_NOTIFY_CEASE, 
        !          1135:                                 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
        !          1136:              return -1;
        !          1137:            }
        !          1138:        }
        !          1139:     }
        !          1140:   return 0;
        !          1141: }
        !          1142: 
        !          1143: static int
        !          1144: bgp_open_receive (struct peer *peer, bgp_size_t size)
        !          1145: {
        !          1146:   int ret;
        !          1147:   u_char version;
        !          1148:   u_char optlen;
        !          1149:   u_int16_t holdtime;
        !          1150:   u_int16_t send_holdtime;
        !          1151:   as_t remote_as;
        !          1152:   as_t as4 = 0;
        !          1153:   struct peer *realpeer;
        !          1154:   struct in_addr remote_id;
        !          1155:   int capability;
        !          1156:   u_int8_t notify_data_remote_as[2];
        !          1157:   u_int8_t notify_data_remote_id[4];
        !          1158: 
        !          1159:   realpeer = NULL;
        !          1160:   
        !          1161:   /* Parse open packet. */
        !          1162:   version = stream_getc (peer->ibuf);
        !          1163:   memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
        !          1164:   remote_as  = stream_getw (peer->ibuf);
        !          1165:   holdtime = stream_getw (peer->ibuf);
        !          1166:   memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
        !          1167:   remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
        !          1168: 
        !          1169:   /* Receive OPEN message log  */
        !          1170:   if (BGP_DEBUG (normal, NORMAL))
        !          1171:     zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
        !          1172:                 " holdtime %d, id %s",
        !          1173:                peer->host, version, remote_as, holdtime,
        !          1174:                inet_ntoa (remote_id));
        !          1175:   
        !          1176:   /* BEGIN to read the capability here, but dont do it yet */
        !          1177:   capability = 0;
        !          1178:   optlen = stream_getc (peer->ibuf);
        !          1179:   
        !          1180:   if (optlen != 0)
        !          1181:     {
        !          1182:       /* We need the as4 capability value *right now* because
        !          1183:        * if it is there, we have not got the remote_as yet, and without
        !          1184:        * that we do not know which peer is connecting to us now.
        !          1185:        */ 
        !          1186:       as4 = peek_for_as4_capability (peer, optlen);
        !          1187:     }
        !          1188:   
        !          1189:   /* Just in case we have a silly peer who sends AS4 capability set to 0 */
        !          1190:   if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
        !          1191:     {
        !          1192:       zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
        !          1193:                 peer->host);
        !          1194:       bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
        !          1195:                        BGP_NOTIFY_OPEN_BAD_PEER_AS);
        !          1196:       return -1;
        !          1197:     }
        !          1198:   
        !          1199:   if (remote_as == BGP_AS_TRANS)
        !          1200:     {
        !          1201:          /* Take the AS4 from the capability.  We must have received the
        !          1202:           * capability now!  Otherwise we have a asn16 peer who uses
        !          1203:           * BGP_AS_TRANS, for some unknown reason.
        !          1204:           */
        !          1205:       if (as4 == BGP_AS_TRANS)
        !          1206:         {
        !          1207:           zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
        !          1208:                     peer->host);
        !          1209:           bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
        !          1210:                  BGP_NOTIFY_OPEN_BAD_PEER_AS);
        !          1211:           return -1;
        !          1212:         }
        !          1213:       
        !          1214:       if (!as4 && BGP_DEBUG (as4, AS4))
        !          1215:         zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
        !          1216:                     " Odd, but proceeding.", peer->host);
        !          1217:       else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
        !          1218:         zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
        !          1219:                     "in 2-bytes, very odd peer.", peer->host, as4);
        !          1220:       if (as4)
        !          1221:         remote_as = as4;
        !          1222:     } 
        !          1223:   else 
        !          1224:     {
        !          1225:       /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
        !          1226:       /* If we have got the capability, peer->as4cap must match remote_as */
        !          1227:       if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
        !          1228:           && as4 != remote_as)
        !          1229:         {
        !          1230:          /* raise error, log this, close session */
        !          1231:          zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
        !          1232:                    " mismatch with 16bit 'myasn' %u in open",
        !          1233:                    peer->host, as4, remote_as);
        !          1234:          bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
        !          1235:                           BGP_NOTIFY_OPEN_BAD_PEER_AS);
        !          1236:          return -1;
        !          1237:        }
        !          1238:     }
        !          1239: 
        !          1240:   /* Lookup peer from Open packet. */
        !          1241:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
        !          1242:     {
        !          1243:       int as = 0;
        !          1244: 
        !          1245:       realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
        !          1246: 
        !          1247:       if (! realpeer)
        !          1248:        {
        !          1249:          /* Peer's source IP address is check in bgp_accept(), so this
        !          1250:             must be AS number mismatch or remote-id configuration
        !          1251:             mismatch. */
        !          1252:          if (as)
        !          1253:            {
        !          1254:              if (BGP_DEBUG (normal, NORMAL))
        !          1255:                zlog_debug ("%s bad OPEN, wrong router identifier %s",
        !          1256:                            peer->host, inet_ntoa (remote_id));
        !          1257:              bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR, 
        !          1258:                                         BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
        !          1259:                                         notify_data_remote_id, 4);
        !          1260:            }
        !          1261:          else
        !          1262:            {
        !          1263:              if (BGP_DEBUG (normal, NORMAL))
        !          1264:                zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
        !          1265:                            peer->host, remote_as, peer->as);
        !          1266:              bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
        !          1267:                                         BGP_NOTIFY_OPEN_BAD_PEER_AS,
        !          1268:                                         notify_data_remote_as, 2);
        !          1269:            }
        !          1270:          return -1;
        !          1271:        }
        !          1272:     }
        !          1273: 
        !          1274:   /* When collision is detected and this peer is closed.  Retrun
        !          1275:      immidiately. */
        !          1276:   ret = bgp_collision_detect (peer, remote_id);
        !          1277:   if (ret < 0)
        !          1278:     return ret;
        !          1279: 
        !          1280:   /* Hack part. */
        !          1281:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
        !          1282:     {
        !          1283:        if (realpeer->status == Established
        !          1284:            && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
        !          1285:        {
        !          1286:          realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
        !          1287:          SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
        !          1288:        }
        !          1289:        else if (ret == 0 && realpeer->status != Active
        !          1290:                 && realpeer->status != OpenSent
        !          1291:                 && realpeer->status != OpenConfirm
        !          1292:                 && realpeer->status != Connect)
        !          1293:        {
        !          1294:          /* XXX: This is an awful problem.. 
        !          1295:           *
        !          1296:           * According to the RFC we should just let this connection (of the
        !          1297:           * accepted 'peer') continue on to Established if the other
        !          1298:           * connection (the 'realpeer' one) is in state Connect, and deal
        !          1299:           * with the more larval FSM as/when it gets far enough to receive
        !          1300:           * an Open. We don't do that though, we instead close the (more
        !          1301:           * developed) accepted connection.
        !          1302:           *
        !          1303:           * This means there's a race, which if hit, can loop:
        !          1304:           *
        !          1305:           *       FSM for A                        FSM for B
        !          1306:           *  realpeer     accept-peer       realpeer     accept-peer
        !          1307:           *
        !          1308:           *  Connect                        Connect
        !          1309:           *               Active
        !          1310:           *               OpenSent          OpenSent
        !          1311:           *               <arrive here,
        !          1312:           *               Notify, delete>   
        !          1313:           *                                 Idle         Active
        !          1314:           *   OpenSent                                   OpenSent
        !          1315:           *                                              <arrive here,
        !          1316:           *                                              Notify, delete>
        !          1317:           *   Idle
        !          1318:           *   <wait>                        <wait>
        !          1319:           *   Connect                       Connect
        !          1320:           *
        !          1321:            *
        !          1322:           * If both sides are Quagga, they're almost certain to wait for
        !          1323:           * the same amount of time of course (which doesn't preclude other
        !          1324:           * implementations also waiting for same time). The race is
        !          1325:           * exacerbated by high-latency (in bgpd and/or the network).
        !          1326:           *
        !          1327:           * The reason we do this is because our FSM is tied to our peer
        !          1328:           * structure, which carries our configuration information, etc. 
        !          1329:           * I.e. we can't let the accepted-peer FSM continue on as it is,
        !          1330:           * cause it's not associated with any actual peer configuration -
        !          1331:           * it's just a dummy.
        !          1332:           *
        !          1333:           * It's possible we could hack-fix this by just bgp_stop'ing the
        !          1334:           * realpeer and continueing on with the 'transfer FSM' below. 
        !          1335:           * Ideally, we need to seperate FSMs from struct peer.
        !          1336:           *
        !          1337:           * Setting one side to passive avoids the race, as a workaround.
        !          1338:           */
        !          1339:          if (BGP_DEBUG (events, EVENTS))
        !          1340:            zlog_debug ("%s peer status is %s close connection",
        !          1341:                        realpeer->host, LOOKUP (bgp_status_msg,
        !          1342:                        realpeer->status));
        !          1343:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
        !          1344:                           BGP_NOTIFY_CEASE_CONNECT_REJECT);
        !          1345: 
        !          1346:          return -1;
        !          1347:        }
        !          1348: 
        !          1349:       if (BGP_DEBUG (events, EVENTS))
        !          1350:        zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
        !          1351:                   peer->host, 
        !          1352:                   LOOKUP (bgp_status_msg, realpeer->status));
        !          1353: 
        !          1354:       bgp_stop (realpeer);
        !          1355:       
        !          1356:       /* Transfer file descriptor. */
        !          1357:       realpeer->fd = peer->fd;
        !          1358:       peer->fd = -1;
        !          1359: 
        !          1360:       /* Transfer input buffer. */
        !          1361:       stream_free (realpeer->ibuf);
        !          1362:       realpeer->ibuf = peer->ibuf;
        !          1363:       realpeer->packet_size = peer->packet_size;
        !          1364:       peer->ibuf = NULL;
        !          1365: 
        !          1366:       /* Transfer status. */
        !          1367:       realpeer->status = peer->status;
        !          1368:       bgp_stop (peer);
        !          1369:       
        !          1370:       /* peer pointer change. Open packet send to neighbor. */
        !          1371:       peer = realpeer;
        !          1372:       bgp_open_send (peer);
        !          1373:       if (peer->fd < 0)
        !          1374:        {
        !          1375:          zlog_err ("bgp_open_receive peer's fd is negative value %d",
        !          1376:                    peer->fd);
        !          1377:          return -1;
        !          1378:        }
        !          1379:       BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
        !          1380:     }
        !          1381: 
        !          1382:   /* remote router-id check. */
        !          1383:   if (remote_id.s_addr == 0
        !          1384:       || ntohl (remote_id.s_addr) >= 0xe0000000
        !          1385:       || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
        !          1386:     {
        !          1387:       if (BGP_DEBUG (normal, NORMAL))
        !          1388:        zlog_debug ("%s bad OPEN, wrong router identifier %s",
        !          1389:                   peer->host, inet_ntoa (remote_id));
        !          1390:       bgp_notify_send_with_data (peer, 
        !          1391:                                 BGP_NOTIFY_OPEN_ERR, 
        !          1392:                                 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
        !          1393:                                 notify_data_remote_id, 4);
        !          1394:       return -1;
        !          1395:     }
        !          1396: 
        !          1397:   /* Set remote router-id */
        !          1398:   peer->remote_id = remote_id;
        !          1399: 
        !          1400:   /* Peer BGP version check. */
        !          1401:   if (version != BGP_VERSION_4)
        !          1402:     {
        !          1403:       u_int8_t maxver = BGP_VERSION_4;
        !          1404:       if (BGP_DEBUG (normal, NORMAL))
        !          1405:        zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
        !          1406:                   peer->host, version, BGP_VERSION_4);
        !          1407:       bgp_notify_send_with_data (peer, 
        !          1408:                                 BGP_NOTIFY_OPEN_ERR, 
        !          1409:                                 BGP_NOTIFY_OPEN_UNSUP_VERSION,
        !          1410:                                 &maxver, 1);
        !          1411:       return -1;
        !          1412:     }
        !          1413: 
        !          1414:   /* Check neighbor as number. */
        !          1415:   if (remote_as != peer->as)
        !          1416:     {
        !          1417:       if (BGP_DEBUG (normal, NORMAL))
        !          1418:        zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
        !          1419:                   peer->host, remote_as, peer->as);
        !          1420:       bgp_notify_send_with_data (peer, 
        !          1421:                                 BGP_NOTIFY_OPEN_ERR, 
        !          1422:                                 BGP_NOTIFY_OPEN_BAD_PEER_AS,
        !          1423:                                 notify_data_remote_as, 2);
        !          1424:       return -1;
        !          1425:     }
        !          1426: 
        !          1427:   /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
        !          1428:      calculate the value of the Hold Timer by using the smaller of its
        !          1429:      configured Hold Time and the Hold Time received in the OPEN message.
        !          1430:      The Hold Time MUST be either zero or at least three seconds.  An
        !          1431:      implementation may reject connections on the basis of the Hold Time. */
        !          1432: 
        !          1433:   if (holdtime < 3 && holdtime != 0)
        !          1434:     {
        !          1435:       bgp_notify_send (peer,
        !          1436:                       BGP_NOTIFY_OPEN_ERR, 
        !          1437:                       BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
        !          1438:       return -1;
        !          1439:     }
        !          1440:     
        !          1441:   /* From the rfc: A reasonable maximum time between KEEPALIVE messages
        !          1442:      would be one third of the Hold Time interval.  KEEPALIVE messages
        !          1443:      MUST NOT be sent more frequently than one per second.  An
        !          1444:      implementation MAY adjust the rate at which it sends KEEPALIVE
        !          1445:      messages as a function of the Hold Time interval. */
        !          1446: 
        !          1447:   if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
        !          1448:     send_holdtime = peer->holdtime;
        !          1449:   else
        !          1450:     send_holdtime = peer->bgp->default_holdtime;
        !          1451: 
        !          1452:   if (holdtime < send_holdtime)
        !          1453:     peer->v_holdtime = holdtime;
        !          1454:   else
        !          1455:     peer->v_holdtime = send_holdtime;
        !          1456: 
        !          1457:   peer->v_keepalive = peer->v_holdtime / 3;
        !          1458: 
        !          1459:   /* Open option part parse. */
        !          1460:   if (optlen != 0) 
        !          1461:     {
        !          1462:       ret = bgp_open_option_parse (peer, optlen, &capability);
        !          1463:       if (ret < 0)
        !          1464:        return ret;
        !          1465:     }
        !          1466:   else
        !          1467:     {
        !          1468:       if (BGP_DEBUG (normal, NORMAL))
        !          1469:        zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
        !          1470:                   peer->host);
        !          1471:     }
        !          1472: 
        !          1473:   /* Override capability. */
        !          1474:   if (! capability || CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
        !          1475:     {
        !          1476:       peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
        !          1477:       peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
        !          1478:       peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
        !          1479:       peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
        !          1480:     }
        !          1481: 
        !          1482:   /* Get sockname. */
        !          1483:   bgp_getsockname (peer);
        !          1484: 
        !          1485:   BGP_EVENT_ADD (peer, Receive_OPEN_message);
        !          1486: 
        !          1487:   peer->packet_size = 0;
        !          1488:   if (peer->ibuf)
        !          1489:     stream_reset (peer->ibuf);
        !          1490: 
        !          1491:   return 0;
        !          1492: }
        !          1493: 
        !          1494: /* Parse BGP Update packet and make attribute object. */
        !          1495: static int
        !          1496: bgp_update_receive (struct peer *peer, bgp_size_t size)
        !          1497: {
        !          1498:   int ret;
        !          1499:   u_char *end;
        !          1500:   struct stream *s;
        !          1501:   struct attr attr;
        !          1502:   bgp_size_t attribute_len;
        !          1503:   bgp_size_t update_len;
        !          1504:   bgp_size_t withdraw_len;
        !          1505:   struct bgp_nlri update;
        !          1506:   struct bgp_nlri withdraw;
        !          1507:   struct bgp_nlri mp_update;
        !          1508:   struct bgp_nlri mp_withdraw;
        !          1509:   char attrstr[BUFSIZ] = "";
        !          1510: 
        !          1511:   /* Status must be Established. */
        !          1512:   if (peer->status != Established) 
        !          1513:     {
        !          1514:       zlog_err ("%s [FSM] Update packet received under status %s",
        !          1515:                peer->host, LOOKUP (bgp_status_msg, peer->status));
        !          1516:       bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
        !          1517:       return -1;
        !          1518:     }
        !          1519: 
        !          1520:   /* Set initial values. */
        !          1521:   memset (&attr, 0, sizeof (struct attr));
        !          1522:   memset (&update, 0, sizeof (struct bgp_nlri));
        !          1523:   memset (&withdraw, 0, sizeof (struct bgp_nlri));
        !          1524:   memset (&mp_update, 0, sizeof (struct bgp_nlri));
        !          1525:   memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
        !          1526: 
        !          1527:   s = peer->ibuf;
        !          1528:   end = stream_pnt (s) + size;
        !          1529: 
        !          1530:   /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
        !          1531:      Length is too large (i.e., if Unfeasible Routes Length + Total
        !          1532:      Attribute Length + 23 exceeds the message Length), then the Error
        !          1533:      Subcode is set to Malformed Attribute List.  */
        !          1534:   if (stream_pnt (s) + 2 > end)
        !          1535:     {
        !          1536:       zlog_err ("%s [Error] Update packet error"
        !          1537:                " (packet length is short for unfeasible length)",
        !          1538:                peer->host);
        !          1539:       bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
        !          1540:                       BGP_NOTIFY_UPDATE_MAL_ATTR);
        !          1541:       return -1;
        !          1542:     }
        !          1543: 
        !          1544:   /* Unfeasible Route Length. */
        !          1545:   withdraw_len = stream_getw (s);
        !          1546: 
        !          1547:   /* Unfeasible Route Length check. */
        !          1548:   if (stream_pnt (s) + withdraw_len > end)
        !          1549:     {
        !          1550:       zlog_err ("%s [Error] Update packet error"
        !          1551:                " (packet unfeasible length overflow %d)",
        !          1552:                peer->host, withdraw_len);
        !          1553:       bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
        !          1554:                       BGP_NOTIFY_UPDATE_MAL_ATTR);
        !          1555:       return -1;
        !          1556:     }
        !          1557: 
        !          1558:   /* Unfeasible Route packet format check. */
        !          1559:   if (withdraw_len > 0)
        !          1560:     {
        !          1561:       ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
        !          1562:       if (ret < 0)
        !          1563:        return -1;
        !          1564: 
        !          1565:       if (BGP_DEBUG (packet, PACKET_RECV))
        !          1566:        zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
        !          1567: 
        !          1568:       withdraw.afi = AFI_IP;
        !          1569:       withdraw.safi = SAFI_UNICAST;
        !          1570:       withdraw.nlri = stream_pnt (s);
        !          1571:       withdraw.length = withdraw_len;
        !          1572:       stream_forward_getp (s, withdraw_len);
        !          1573:     }
        !          1574:   
        !          1575:   /* Attribute total length check. */
        !          1576:   if (stream_pnt (s) + 2 > end)
        !          1577:     {
        !          1578:       zlog_warn ("%s [Error] Packet Error"
        !          1579:                 " (update packet is short for attribute length)",
        !          1580:                 peer->host);
        !          1581:       bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
        !          1582:                       BGP_NOTIFY_UPDATE_MAL_ATTR);
        !          1583:       return -1;
        !          1584:     }
        !          1585: 
        !          1586:   /* Fetch attribute total length. */
        !          1587:   attribute_len = stream_getw (s);
        !          1588: 
        !          1589:   /* Attribute length check. */
        !          1590:   if (stream_pnt (s) + attribute_len > end)
        !          1591:     {
        !          1592:       zlog_warn ("%s [Error] Packet Error"
        !          1593:                 " (update packet attribute length overflow %d)",
        !          1594:                 peer->host, attribute_len);
        !          1595:       bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
        !          1596:                       BGP_NOTIFY_UPDATE_MAL_ATTR);
        !          1597:       return -1;
        !          1598:     }
        !          1599:   
        !          1600:   /* Certain attribute parsing errors should not be considered bad enough
        !          1601:    * to reset the session for, most particularly any partial/optional
        !          1602:    * attributes that have 'tunneled' over speakers that don't understand
        !          1603:    * them. Instead we withdraw only the prefix concerned.
        !          1604:    * 
        !          1605:    * Complicates the flow a little though..
        !          1606:    */
        !          1607:   bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
        !          1608:   /* This define morphs the update case into a withdraw when lower levels
        !          1609:    * have signalled an error condition where this is best.
        !          1610:    */
        !          1611: #define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
        !          1612: 
        !          1613:   /* Parse attribute when it exists. */
        !          1614:   if (attribute_len)
        !          1615:     {
        !          1616:       attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len, 
        !          1617:                            &mp_update, &mp_withdraw);
        !          1618:       if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
        !          1619:        return -1;
        !          1620:     }
        !          1621:   
        !          1622:   /* Logging the attribute. */
        !          1623:   if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
        !          1624:       || BGP_DEBUG (update, UPDATE_IN))
        !          1625:     {
        !          1626:       ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
        !          1627:       int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
        !          1628:                  ? LOG_ERR : LOG_DEBUG;
        !          1629:       
        !          1630:       if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
        !          1631:         zlog (peer->log, LOG_ERR,
        !          1632:               "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
        !          1633:               peer->host);
        !          1634: 
        !          1635:       if (ret)
        !          1636:        zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
        !          1637:              peer->host, attrstr);
        !          1638:     }
        !          1639:   
        !          1640:   /* Network Layer Reachability Information. */
        !          1641:   update_len = end - stream_pnt (s);
        !          1642: 
        !          1643:   if (update_len)
        !          1644:     {
        !          1645:       /* Check NLRI packet format and prefix length. */
        !          1646:       ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
        !          1647:       if (ret < 0)
        !          1648:         {
        !          1649:           bgp_attr_unintern_sub (&attr);
        !          1650:           if (attr.extra)
        !          1651:             bgp_attr_extra_free (&attr);
        !          1652:          return -1;
        !          1653:        }
        !          1654: 
        !          1655:       /* Set NLRI portion to structure. */
        !          1656:       update.afi = AFI_IP;
        !          1657:       update.safi = SAFI_UNICAST;
        !          1658:       update.nlri = stream_pnt (s);
        !          1659:       update.length = update_len;
        !          1660:       stream_forward_getp (s, update_len);
        !          1661:     }
        !          1662: 
        !          1663:   /* NLRI is processed only when the peer is configured specific
        !          1664:      Address Family and Subsequent Address Family. */
        !          1665:   if (peer->afc[AFI_IP][SAFI_UNICAST])
        !          1666:     {
        !          1667:       if (withdraw.length)
        !          1668:        bgp_nlri_parse (peer, NULL, &withdraw);
        !          1669: 
        !          1670:       if (update.length)
        !          1671:        {
        !          1672:          /* We check well-known attribute only for IPv4 unicast
        !          1673:             update. */
        !          1674:          ret = bgp_attr_check (peer, &attr);
        !          1675:          if (ret < 0)
        !          1676:            {
        !          1677:              bgp_attr_unintern_sub (&attr);
        !          1678:               if (attr.extra)
        !          1679:                 bgp_attr_extra_free (&attr);
        !          1680:              return -1;
        !          1681:             }
        !          1682: 
        !          1683:          bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
        !          1684:        }
        !          1685: 
        !          1686:       if (mp_update.length
        !          1687:          && mp_update.afi == AFI_IP 
        !          1688:          && mp_update.safi == SAFI_UNICAST)
        !          1689:        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
        !          1690: 
        !          1691:       if (mp_withdraw.length
        !          1692:          && mp_withdraw.afi == AFI_IP 
        !          1693:          && mp_withdraw.safi == SAFI_UNICAST)
        !          1694:        bgp_nlri_parse (peer, NULL, &mp_withdraw);
        !          1695: 
        !          1696:       if (! attribute_len && ! withdraw_len)
        !          1697:        {
        !          1698:          /* End-of-RIB received */
        !          1699:          SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
        !          1700:                    PEER_STATUS_EOR_RECEIVED);
        !          1701: 
        !          1702:          /* NSF delete stale route */
        !          1703:          if (peer->nsf[AFI_IP][SAFI_UNICAST])
        !          1704:            bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
        !          1705: 
        !          1706:          if (BGP_DEBUG (normal, NORMAL))
        !          1707:            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
        !          1708:                  peer->host);
        !          1709:        }
        !          1710:     }
        !          1711:   if (peer->afc[AFI_IP][SAFI_MULTICAST])
        !          1712:     {
        !          1713:       if (mp_update.length
        !          1714:          && mp_update.afi == AFI_IP 
        !          1715:          && mp_update.safi == SAFI_MULTICAST)
        !          1716:        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
        !          1717: 
        !          1718:       if (mp_withdraw.length
        !          1719:          && mp_withdraw.afi == AFI_IP 
        !          1720:          && mp_withdraw.safi == SAFI_MULTICAST)
        !          1721:        bgp_nlri_parse (peer, NULL, &mp_withdraw);
        !          1722: 
        !          1723:       if (! withdraw_len
        !          1724:          && mp_withdraw.afi == AFI_IP
        !          1725:          && mp_withdraw.safi == SAFI_MULTICAST
        !          1726:          && mp_withdraw.length == 0)
        !          1727:        {
        !          1728:          /* End-of-RIB received */
        !          1729:          SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
        !          1730:                    PEER_STATUS_EOR_RECEIVED);
        !          1731: 
        !          1732:          /* NSF delete stale route */
        !          1733:          if (peer->nsf[AFI_IP][SAFI_MULTICAST])
        !          1734:            bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
        !          1735: 
        !          1736:          if (BGP_DEBUG (normal, NORMAL))
        !          1737:            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
        !          1738:                  peer->host);
        !          1739:        }
        !          1740:     }
        !          1741:   if (peer->afc[AFI_IP6][SAFI_UNICAST])
        !          1742:     {
        !          1743:       if (mp_update.length 
        !          1744:          && mp_update.afi == AFI_IP6 
        !          1745:          && mp_update.safi == SAFI_UNICAST)
        !          1746:        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
        !          1747: 
        !          1748:       if (mp_withdraw.length 
        !          1749:          && mp_withdraw.afi == AFI_IP6 
        !          1750:          && mp_withdraw.safi == SAFI_UNICAST)
        !          1751:        bgp_nlri_parse (peer, NULL, &mp_withdraw);
        !          1752: 
        !          1753:       if (! withdraw_len
        !          1754:          && mp_withdraw.afi == AFI_IP6
        !          1755:          && mp_withdraw.safi == SAFI_UNICAST
        !          1756:          && mp_withdraw.length == 0)
        !          1757:        {
        !          1758:          /* End-of-RIB received */
        !          1759:          SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
        !          1760: 
        !          1761:          /* NSF delete stale route */
        !          1762:          if (peer->nsf[AFI_IP6][SAFI_UNICAST])
        !          1763:            bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
        !          1764: 
        !          1765:          if (BGP_DEBUG (normal, NORMAL))
        !          1766:            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
        !          1767:                  peer->host);
        !          1768:        }
        !          1769:     }
        !          1770:   if (peer->afc[AFI_IP6][SAFI_MULTICAST])
        !          1771:     {
        !          1772:       if (mp_update.length 
        !          1773:          && mp_update.afi == AFI_IP6 
        !          1774:          && mp_update.safi == SAFI_MULTICAST)
        !          1775:        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
        !          1776: 
        !          1777:       if (mp_withdraw.length 
        !          1778:          && mp_withdraw.afi == AFI_IP6 
        !          1779:          && mp_withdraw.safi == SAFI_MULTICAST)
        !          1780:        bgp_nlri_parse (peer, NULL, &mp_withdraw);
        !          1781: 
        !          1782:       if (! withdraw_len
        !          1783:          && mp_withdraw.afi == AFI_IP6
        !          1784:          && mp_withdraw.safi == SAFI_MULTICAST
        !          1785:          && mp_withdraw.length == 0)
        !          1786:        {
        !          1787:          /* End-of-RIB received */
        !          1788: 
        !          1789:          /* NSF delete stale route */
        !          1790:          if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
        !          1791:            bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
        !          1792: 
        !          1793:          if (BGP_DEBUG (update, UPDATE_IN))
        !          1794:            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
        !          1795:                  peer->host);
        !          1796:        }
        !          1797:     }
        !          1798:   if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
        !          1799:     {
        !          1800:       if (mp_update.length 
        !          1801:          && mp_update.afi == AFI_IP 
        !          1802:          && mp_update.safi == BGP_SAFI_VPNV4)
        !          1803:        bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update);
        !          1804: 
        !          1805:       if (mp_withdraw.length 
        !          1806:          && mp_withdraw.afi == AFI_IP 
        !          1807:          && mp_withdraw.safi == BGP_SAFI_VPNV4)
        !          1808:        bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
        !          1809: 
        !          1810:       if (! withdraw_len
        !          1811:          && mp_withdraw.afi == AFI_IP
        !          1812:          && mp_withdraw.safi == BGP_SAFI_VPNV4
        !          1813:          && mp_withdraw.length == 0)
        !          1814:        {
        !          1815:          /* End-of-RIB received */
        !          1816: 
        !          1817:          if (BGP_DEBUG (update, UPDATE_IN))
        !          1818:            zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
        !          1819:                  peer->host);
        !          1820:        }
        !          1821:     }
        !          1822: 
        !          1823:   /* Everything is done.  We unintern temporary structures which
        !          1824:      interned in bgp_attr_parse(). */
        !          1825:   bgp_attr_unintern_sub (&attr);
        !          1826:   if (attr.extra)
        !          1827:     bgp_attr_extra_free (&attr);
        !          1828:   
        !          1829:   /* If peering is stopped due to some reason, do not generate BGP
        !          1830:      event.  */
        !          1831:   if (peer->status != Established)
        !          1832:     return 0;
        !          1833: 
        !          1834:   /* Increment packet counter. */
        !          1835:   peer->update_in++;
        !          1836:   peer->update_time = bgp_clock ();
        !          1837: 
        !          1838:   /* Generate BGP event. */
        !          1839:   BGP_EVENT_ADD (peer, Receive_UPDATE_message);
        !          1840: 
        !          1841:   return 0;
        !          1842: }
        !          1843: 
        !          1844: /* Notify message treatment function. */
        !          1845: static void
        !          1846: bgp_notify_receive (struct peer *peer, bgp_size_t size)
        !          1847: {
        !          1848:   struct bgp_notify bgp_notify;
        !          1849: 
        !          1850:   if (peer->notify.data)
        !          1851:     {
        !          1852:       XFREE (MTYPE_TMP, peer->notify.data);
        !          1853:       peer->notify.data = NULL;
        !          1854:       peer->notify.length = 0;
        !          1855:     }
        !          1856: 
        !          1857:   bgp_notify.code = stream_getc (peer->ibuf);
        !          1858:   bgp_notify.subcode = stream_getc (peer->ibuf);
        !          1859:   bgp_notify.length = size - 2;
        !          1860:   bgp_notify.data = NULL;
        !          1861: 
        !          1862:   /* Preserv notify code and sub code. */
        !          1863:   peer->notify.code = bgp_notify.code;
        !          1864:   peer->notify.subcode = bgp_notify.subcode;
        !          1865:   /* For further diagnostic record returned Data. */
        !          1866:   if (bgp_notify.length)
        !          1867:     {
        !          1868:       peer->notify.length = size - 2;
        !          1869:       peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
        !          1870:       memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
        !          1871:     }
        !          1872: 
        !          1873:   /* For debug */
        !          1874:   {
        !          1875:     int i;
        !          1876:     int first = 0;
        !          1877:     char c[4];
        !          1878: 
        !          1879:     if (bgp_notify.length)
        !          1880:       {
        !          1881:        bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
        !          1882:        for (i = 0; i < bgp_notify.length; i++)
        !          1883:          if (first)
        !          1884:            {
        !          1885:              sprintf (c, " %02x", stream_getc (peer->ibuf));
        !          1886:              strcat (bgp_notify.data, c);
        !          1887:            }
        !          1888:          else
        !          1889:            {
        !          1890:              first = 1;
        !          1891:              sprintf (c, "%02x", stream_getc (peer->ibuf));
        !          1892:              strcpy (bgp_notify.data, c);
        !          1893:            }
        !          1894:       }
        !          1895: 
        !          1896:     bgp_notify_print(peer, &bgp_notify, "received");
        !          1897:     if (bgp_notify.data)
        !          1898:       XFREE (MTYPE_TMP, bgp_notify.data);
        !          1899:   }
        !          1900: 
        !          1901:   /* peer count update */
        !          1902:   peer->notify_in++;
        !          1903: 
        !          1904:   if (peer->status == Established)
        !          1905:     peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
        !          1906: 
        !          1907:   /* We have to check for Notify with Unsupported Optional Parameter.
        !          1908:      in that case we fallback to open without the capability option.
        !          1909:      But this done in bgp_stop. We just mark it here to avoid changing
        !          1910:      the fsm tables.  */
        !          1911:   if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
        !          1912:       bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
        !          1913:     UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
        !          1914: 
        !          1915:   BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
        !          1916: }
        !          1917: 
        !          1918: /* Keepalive treatment function -- get keepalive send keepalive */
        !          1919: static void
        !          1920: bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
        !          1921: {
        !          1922:   if (BGP_DEBUG (keepalive, KEEPALIVE))  
        !          1923:     zlog_debug ("%s KEEPALIVE rcvd", peer->host); 
        !          1924:   
        !          1925:   BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
        !          1926: }
        !          1927: 
        !          1928: /* Route refresh message is received. */
        !          1929: static void
        !          1930: bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
        !          1931: {
        !          1932:   afi_t afi;
        !          1933:   safi_t safi;
        !          1934:   u_char reserved;
        !          1935:   struct stream *s;
        !          1936: 
        !          1937:   /* If peer does not have the capability, send notification. */
        !          1938:   if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
        !          1939:     {
        !          1940:       plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
        !          1941:                peer->host);
        !          1942:       bgp_notify_send (peer,
        !          1943:                       BGP_NOTIFY_HEADER_ERR,
        !          1944:                       BGP_NOTIFY_HEADER_BAD_MESTYPE);
        !          1945:       return;
        !          1946:     }
        !          1947: 
        !          1948:   /* Status must be Established. */
        !          1949:   if (peer->status != Established) 
        !          1950:     {
        !          1951:       plog_err (peer->log,
        !          1952:                "%s [Error] Route refresh packet received under status %s",
        !          1953:                peer->host, LOOKUP (bgp_status_msg, peer->status));
        !          1954:       bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
        !          1955:       return;
        !          1956:     }
        !          1957: 
        !          1958:   s = peer->ibuf;
        !          1959:   
        !          1960:   /* Parse packet. */
        !          1961:   afi = stream_getw (s);
        !          1962:   reserved = stream_getc (s);
        !          1963:   safi = stream_getc (s);
        !          1964: 
        !          1965:   if (BGP_DEBUG (normal, NORMAL))
        !          1966:     zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
        !          1967:               peer->host, afi, safi);
        !          1968: 
        !          1969:   /* Check AFI and SAFI. */
        !          1970:   if ((afi != AFI_IP && afi != AFI_IP6)
        !          1971:       || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
        !          1972:          && safi != BGP_SAFI_VPNV4))
        !          1973:     {
        !          1974:       if (BGP_DEBUG (normal, NORMAL))
        !          1975:        {
        !          1976:          zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
        !          1977:                     peer->host, afi, safi);
        !          1978:        }
        !          1979:       return;
        !          1980:     }
        !          1981: 
        !          1982:   /* Adjust safi code. */
        !          1983:   if (safi == BGP_SAFI_VPNV4)
        !          1984:     safi = SAFI_MPLS_VPN;
        !          1985: 
        !          1986:   if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
        !          1987:     {
        !          1988:       u_char *end;
        !          1989:       u_char when_to_refresh;
        !          1990:       u_char orf_type;
        !          1991:       u_int16_t orf_len;
        !          1992: 
        !          1993:       if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
        !          1994:         {
        !          1995:           zlog_info ("%s ORF route refresh length error", peer->host);
        !          1996:           bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
        !          1997:           return;
        !          1998:         }
        !          1999: 
        !          2000:       when_to_refresh = stream_getc (s);
        !          2001:       end = stream_pnt (s) + (size - 5);
        !          2002: 
        !          2003:       while ((stream_pnt (s) + 2) < end)
        !          2004:        {
        !          2005:          orf_type = stream_getc (s); 
        !          2006:          orf_len = stream_getw (s);
        !          2007:          
        !          2008:          /* orf_len in bounds? */
        !          2009:          if ((stream_pnt (s) + orf_len) > end)
        !          2010:            break; /* XXX: Notify instead?? */
        !          2011:          if (orf_type == ORF_TYPE_PREFIX
        !          2012:              || orf_type == ORF_TYPE_PREFIX_OLD)
        !          2013:            {
        !          2014:              u_char *p_pnt = stream_pnt (s);
        !          2015:              u_char *p_end = stream_pnt (s) + orf_len;
        !          2016:              struct orf_prefix orfp;
        !          2017:              u_char common = 0;
        !          2018:              u_int32_t seq;
        !          2019:              int psize;
        !          2020:              char name[BUFSIZ];
        !          2021:              char buf[BUFSIZ];
        !          2022:              int ret;
        !          2023: 
        !          2024:              if (BGP_DEBUG (normal, NORMAL))
        !          2025:                {
        !          2026:                  zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
        !          2027:                             peer->host, orf_type, orf_len);
        !          2028:                }
        !          2029: 
        !          2030:               /* we're going to read at least 1 byte of common ORF header,
        !          2031:                * and 7 bytes of ORF Address-filter entry from the stream
        !          2032:                */
        !          2033:               if (orf_len < 7)
        !          2034:                 break; 
        !          2035:                 
        !          2036:              /* ORF prefix-list name */
        !          2037:              sprintf (name, "%s.%d.%d", peer->host, afi, safi);
        !          2038: 
        !          2039:              while (p_pnt < p_end)
        !          2040:                {
        !          2041:                   /* If the ORF entry is malformed, want to read as much of it
        !          2042:                    * as possible without going beyond the bounds of the entry,
        !          2043:                    * to maximise debug information.
        !          2044:                    */
        !          2045:                  int ok;
        !          2046:                  memset (&orfp, 0, sizeof (struct orf_prefix));
        !          2047:                  common = *p_pnt++;
        !          2048:                  /* after ++: p_pnt <= p_end */
        !          2049:                  if (common & ORF_COMMON_PART_REMOVE_ALL)
        !          2050:                    {
        !          2051:                      if (BGP_DEBUG (normal, NORMAL))
        !          2052:                        zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
        !          2053:                      prefix_bgp_orf_remove_all (name);
        !          2054:                      break;
        !          2055:                    }
        !          2056:                  ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ;
        !          2057:                  if (!ok)
        !          2058:                    {
        !          2059:                      memcpy (&seq, p_pnt, sizeof (u_int32_t));
        !          2060:                       p_pnt += sizeof (u_int32_t);
        !          2061:                       orfp.seq = ntohl (seq);
        !          2062:                    }
        !          2063:                  else
        !          2064:                    p_pnt = p_end ;
        !          2065: 
        !          2066:                  if ((ok = (p_pnt < p_end)))
        !          2067:                    orfp.ge = *p_pnt++ ;      /* value checked in prefix_bgp_orf_set() */
        !          2068:                  if ((ok = (p_pnt < p_end)))
        !          2069:                    orfp.le = *p_pnt++ ;      /* value checked in prefix_bgp_orf_set() */
        !          2070:                  if ((ok = (p_pnt < p_end)))
        !          2071:                    orfp.p.prefixlen = *p_pnt++ ;
        !          2072:                  orfp.p.family = afi2family (afi);   /* afi checked already  */
        !          2073: 
        !          2074:                  psize = PSIZE (orfp.p.prefixlen);   /* 0 if not ok          */
        !          2075:                  if (psize > prefix_blen(&orfp.p))   /* valid for family ?   */
        !          2076:                    {
        !          2077:                      ok = 0 ;
        !          2078:                      psize = prefix_blen(&orfp.p) ;
        !          2079:                    }
        !          2080:                  if (psize > (p_end - p_pnt))        /* valid for packet ?   */
        !          2081:                    {
        !          2082:                      ok = 0 ;
        !          2083:                      psize = p_end - p_pnt ;
        !          2084:                    }
        !          2085: 
        !          2086:                  if (psize > 0)
        !          2087:                    memcpy (&orfp.p.u.prefix, p_pnt, psize);
        !          2088:                  p_pnt += psize;
        !          2089: 
        !          2090:                  if (BGP_DEBUG (normal, NORMAL))
        !          2091:                    zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
        !          2092:                               peer->host,
        !          2093:                               (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"), 
        !          2094:                               (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
        !          2095:                               orfp.seq, 
        !          2096:                               inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ),
        !          2097:                               orfp.p.prefixlen, orfp.ge, orfp.le,
        !          2098:                               ok ? "" : " MALFORMED");
        !          2099:                   
        !          2100:                  if (ok)
        !          2101:                    ret = prefix_bgp_orf_set (name, afi, &orfp,
        !          2102:                                   (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
        !          2103:                                   (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
        !          2104: 
        !          2105:                  if (!ok || (ret != CMD_SUCCESS))
        !          2106:                    {
        !          2107:                      if (BGP_DEBUG (normal, NORMAL))
        !          2108:                        zlog_debug ("%s Received misformatted prefixlist ORF."
        !          2109:                                    " Remove All pfxlist", peer->host);
        !          2110:                      prefix_bgp_orf_remove_all (name);
        !          2111:                      break;
        !          2112:                    }
        !          2113:                }
        !          2114:              peer->orf_plist[afi][safi] =
        !          2115:                         prefix_list_lookup (AFI_ORF_PREFIX, name);
        !          2116:            }
        !          2117:          stream_forward_getp (s, orf_len);
        !          2118:        }
        !          2119:       if (BGP_DEBUG (normal, NORMAL))
        !          2120:        zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
        !          2121:                   when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
        !          2122:       if (when_to_refresh == REFRESH_DEFER)
        !          2123:        return;
        !          2124:     }
        !          2125: 
        !          2126:   /* First update is deferred until ORF or ROUTE-REFRESH is received */
        !          2127:   if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
        !          2128:     UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
        !          2129: 
        !          2130:   /* Perform route refreshment to the peer */
        !          2131:   bgp_announce_route (peer, afi, safi);
        !          2132: }
        !          2133: 
        !          2134: static int
        !          2135: bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
        !          2136: {
        !          2137:   u_char *end;
        !          2138:   struct capability_mp_data mpc;
        !          2139:   struct capability_header *hdr;
        !          2140:   u_char action;
        !          2141:   struct bgp *bgp;
        !          2142:   afi_t afi;
        !          2143:   safi_t safi;
        !          2144: 
        !          2145:   bgp = peer->bgp;
        !          2146:   end = pnt + length;
        !          2147: 
        !          2148:   while (pnt < end)
        !          2149:     {      
        !          2150:       /* We need at least action, capability code and capability length. */
        !          2151:       if (pnt + 3 > end)
        !          2152:         {
        !          2153:           zlog_info ("%s Capability length error", peer->host);
        !          2154:           bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
        !          2155:           return -1;
        !          2156:         }
        !          2157:       action = *pnt;
        !          2158:       hdr = (struct capability_header *)(pnt + 1);
        !          2159:       
        !          2160:       /* Action value check.  */
        !          2161:       if (action != CAPABILITY_ACTION_SET
        !          2162:          && action != CAPABILITY_ACTION_UNSET)
        !          2163:         {
        !          2164:           zlog_info ("%s Capability Action Value error %d",
        !          2165:                     peer->host, action);
        !          2166:           bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
        !          2167:           return -1;
        !          2168:         }
        !          2169: 
        !          2170:       if (BGP_DEBUG (normal, NORMAL))
        !          2171:        zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
        !          2172:                   peer->host, action, hdr->code, hdr->length);
        !          2173: 
        !          2174:       /* Capability length check. */
        !          2175:       if ((pnt + hdr->length + 3) > end)
        !          2176:         {
        !          2177:           zlog_info ("%s Capability length error", peer->host);
        !          2178:           bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
        !          2179:           return -1;
        !          2180:         }
        !          2181: 
        !          2182:       /* Fetch structure to the byte stream. */
        !          2183:       memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
        !          2184: 
        !          2185:       /* We know MP Capability Code. */
        !          2186:       if (hdr->code == CAPABILITY_CODE_MP)
        !          2187:         {
        !          2188:          afi = ntohs (mpc.afi);
        !          2189:          safi = mpc.safi;
        !          2190: 
        !          2191:           /* Ignore capability when override-capability is set. */
        !          2192:           if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
        !          2193:            continue;
        !          2194:           
        !          2195:           if (!bgp_afi_safi_valid_indices (afi, &safi))
        !          2196:             {
        !          2197:               if (BGP_DEBUG (normal, NORMAL))
        !          2198:                 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
        !          2199:                             "(%u/%u)", peer->host, afi, safi);
        !          2200:               continue;
        !          2201:             }
        !          2202:           
        !          2203:          /* Address family check.  */
        !          2204:           if (BGP_DEBUG (normal, NORMAL))
        !          2205:             zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
        !          2206:                        peer->host,
        !          2207:                        action == CAPABILITY_ACTION_SET 
        !          2208:                        ? "Advertising" : "Removing",
        !          2209:                        ntohs(mpc.afi) , mpc.safi);
        !          2210:               
        !          2211:           if (action == CAPABILITY_ACTION_SET)
        !          2212:             {
        !          2213:               peer->afc_recv[afi][safi] = 1;
        !          2214:               if (peer->afc[afi][safi])
        !          2215:                 {
        !          2216:                   peer->afc_nego[afi][safi] = 1;
        !          2217:                   bgp_announce_route (peer, afi, safi);
        !          2218:                 }
        !          2219:             }
        !          2220:           else
        !          2221:             {
        !          2222:               peer->afc_recv[afi][safi] = 0;
        !          2223:               peer->afc_nego[afi][safi] = 0;
        !          2224: 
        !          2225:               if (peer_active_nego (peer))
        !          2226:                 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
        !          2227:               else
        !          2228:                 BGP_EVENT_ADD (peer, BGP_Stop);
        !          2229:             }
        !          2230:         }
        !          2231:       else
        !          2232:         {
        !          2233:           zlog_warn ("%s unrecognized capability code: %d - ignored",
        !          2234:                      peer->host, hdr->code);
        !          2235:         }
        !          2236:       pnt += hdr->length + 3;
        !          2237:     }
        !          2238:   return 0;
        !          2239: }
        !          2240: 
        !          2241: /* Dynamic Capability is received. 
        !          2242:  *
        !          2243:  * This is exported for unit-test purposes
        !          2244:  */
        !          2245: int
        !          2246: bgp_capability_receive (struct peer *peer, bgp_size_t size)
        !          2247: {
        !          2248:   u_char *pnt;
        !          2249: 
        !          2250:   /* Fetch pointer. */
        !          2251:   pnt = stream_pnt (peer->ibuf);
        !          2252: 
        !          2253:   if (BGP_DEBUG (normal, NORMAL))
        !          2254:     zlog_debug ("%s rcv CAPABILITY", peer->host);
        !          2255: 
        !          2256:   /* If peer does not have the capability, send notification. */
        !          2257:   if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
        !          2258:     {
        !          2259:       plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
        !          2260:                peer->host);
        !          2261:       bgp_notify_send (peer,
        !          2262:                       BGP_NOTIFY_HEADER_ERR,
        !          2263:                       BGP_NOTIFY_HEADER_BAD_MESTYPE);
        !          2264:       return -1;
        !          2265:     }
        !          2266: 
        !          2267:   /* Status must be Established. */
        !          2268:   if (peer->status != Established)
        !          2269:     {
        !          2270:       plog_err (peer->log,
        !          2271:                "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
        !          2272:       bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
        !          2273:       return -1;
        !          2274:     }
        !          2275: 
        !          2276:   /* Parse packet. */
        !          2277:   return bgp_capability_msg_parse (peer, pnt, size);
        !          2278: }
        !          2279: 
        !          2280: /* BGP read utility function. */
        !          2281: static int
        !          2282: bgp_read_packet (struct peer *peer)
        !          2283: {
        !          2284:   int nbytes;
        !          2285:   int readsize;
        !          2286: 
        !          2287:   readsize = peer->packet_size - stream_get_endp (peer->ibuf);
        !          2288: 
        !          2289:   /* If size is zero then return. */
        !          2290:   if (! readsize)
        !          2291:     return 0;
        !          2292: 
        !          2293:   /* Read packet from fd. */
        !          2294:   nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
        !          2295: 
        !          2296:   /* If read byte is smaller than zero then error occured. */
        !          2297:   if (nbytes < 0) 
        !          2298:     {
        !          2299:       /* Transient error should retry */
        !          2300:       if (nbytes == -2)
        !          2301:        return -1;
        !          2302: 
        !          2303:       plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
        !          2304:                 peer->host, safe_strerror (errno));
        !          2305: 
        !          2306:       if (peer->status == Established) 
        !          2307:        {
        !          2308:          if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
        !          2309:            {
        !          2310:              peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
        !          2311:              SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
        !          2312:            }
        !          2313:          else
        !          2314:            peer->last_reset = PEER_DOWN_CLOSE_SESSION;
        !          2315:        }
        !          2316: 
        !          2317:       BGP_EVENT_ADD (peer, TCP_fatal_error);
        !          2318:       return -1;
        !          2319:     }  
        !          2320: 
        !          2321:   /* When read byte is zero : clear bgp peer and return */
        !          2322:   if (nbytes == 0) 
        !          2323:     {
        !          2324:       if (BGP_DEBUG (events, EVENTS))
        !          2325:        plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
        !          2326:                   peer->host, peer->fd);
        !          2327: 
        !          2328:       if (peer->status == Established) 
        !          2329:        {
        !          2330:          if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
        !          2331:            {
        !          2332:              peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
        !          2333:              SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
        !          2334:            }
        !          2335:          else
        !          2336:            peer->last_reset = PEER_DOWN_CLOSE_SESSION;
        !          2337:        }
        !          2338: 
        !          2339:       BGP_EVENT_ADD (peer, TCP_connection_closed);
        !          2340:       return -1;
        !          2341:     }
        !          2342: 
        !          2343:   /* We read partial packet. */
        !          2344:   if (stream_get_endp (peer->ibuf) != peer->packet_size)
        !          2345:     return -1;
        !          2346: 
        !          2347:   return 0;
        !          2348: }
        !          2349: 
        !          2350: /* Marker check. */
        !          2351: static int
        !          2352: bgp_marker_all_one (struct stream *s, int length)
        !          2353: {
        !          2354:   int i;
        !          2355: 
        !          2356:   for (i = 0; i < length; i++)
        !          2357:     if (s->data[i] != 0xff)
        !          2358:       return 0;
        !          2359: 
        !          2360:   return 1;
        !          2361: }
        !          2362: 
        !          2363: /* Starting point of packet process function. */
        !          2364: int
        !          2365: bgp_read (struct thread *thread)
        !          2366: {
        !          2367:   int ret;
        !          2368:   u_char type = 0;
        !          2369:   struct peer *peer;
        !          2370:   bgp_size_t size;
        !          2371:   char notify_data_length[2];
        !          2372: 
        !          2373:   /* Yes first of all get peer pointer. */
        !          2374:   peer = THREAD_ARG (thread);
        !          2375:   peer->t_read = NULL;
        !          2376: 
        !          2377:   /* For non-blocking IO check. */
        !          2378:   if (peer->status == Connect)
        !          2379:     {
        !          2380:       bgp_connect_check (peer);
        !          2381:       goto done;
        !          2382:     }
        !          2383:   else
        !          2384:     {
        !          2385:       if (peer->fd < 0)
        !          2386:        {
        !          2387:          zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
        !          2388:          return -1;
        !          2389:        }
        !          2390:       BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
        !          2391:     }
        !          2392: 
        !          2393:   /* Read packet header to determine type of the packet */
        !          2394:   if (peer->packet_size == 0)
        !          2395:     peer->packet_size = BGP_HEADER_SIZE;
        !          2396: 
        !          2397:   if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
        !          2398:     {
        !          2399:       ret = bgp_read_packet (peer);
        !          2400: 
        !          2401:       /* Header read error or partial read packet. */
        !          2402:       if (ret < 0) 
        !          2403:        goto done;
        !          2404: 
        !          2405:       /* Get size and type. */
        !          2406:       stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
        !          2407:       memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
        !          2408:       size = stream_getw (peer->ibuf);
        !          2409:       type = stream_getc (peer->ibuf);
        !          2410: 
        !          2411:       if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
        !          2412:        zlog_debug ("%s rcv message type %d, length (excl. header) %d",
        !          2413:                   peer->host, type, size - BGP_HEADER_SIZE);
        !          2414: 
        !          2415:       /* Marker check */
        !          2416:       if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
        !          2417:          && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
        !          2418:        {
        !          2419:          bgp_notify_send (peer,
        !          2420:                           BGP_NOTIFY_HEADER_ERR, 
        !          2421:                           BGP_NOTIFY_HEADER_NOT_SYNC);
        !          2422:          goto done;
        !          2423:        }
        !          2424: 
        !          2425:       /* BGP type check. */
        !          2426:       if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE 
        !          2427:          && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE 
        !          2428:          && type != BGP_MSG_ROUTE_REFRESH_NEW
        !          2429:          && type != BGP_MSG_ROUTE_REFRESH_OLD
        !          2430:          && type != BGP_MSG_CAPABILITY)
        !          2431:        {
        !          2432:          if (BGP_DEBUG (normal, NORMAL))
        !          2433:            plog_debug (peer->log,
        !          2434:                      "%s unknown message type 0x%02x",
        !          2435:                      peer->host, type);
        !          2436:          bgp_notify_send_with_data (peer,
        !          2437:                                     BGP_NOTIFY_HEADER_ERR,
        !          2438:                                     BGP_NOTIFY_HEADER_BAD_MESTYPE,
        !          2439:                                     &type, 1);
        !          2440:          goto done;
        !          2441:        }
        !          2442:       /* Mimimum packet length check. */
        !          2443:       if ((size < BGP_HEADER_SIZE)
        !          2444:          || (size > BGP_MAX_PACKET_SIZE)
        !          2445:          || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
        !          2446:          || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
        !          2447:          || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
        !          2448:          || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
        !          2449:          || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
        !          2450:          || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
        !          2451:          || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
        !          2452:        {
        !          2453:          if (BGP_DEBUG (normal, NORMAL))
        !          2454:            plog_debug (peer->log,
        !          2455:                      "%s bad message length - %d for %s",
        !          2456:                      peer->host, size, 
        !          2457:                      type == 128 ? "ROUTE-REFRESH" :
        !          2458:                      bgp_type_str[(int) type]);
        !          2459:          bgp_notify_send_with_data (peer,
        !          2460:                                     BGP_NOTIFY_HEADER_ERR,
        !          2461:                                     BGP_NOTIFY_HEADER_BAD_MESLEN,
        !          2462:                                     (u_char *) notify_data_length, 2);
        !          2463:          goto done;
        !          2464:        }
        !          2465: 
        !          2466:       /* Adjust size to message length. */
        !          2467:       peer->packet_size = size;
        !          2468:     }
        !          2469: 
        !          2470:   ret = bgp_read_packet (peer);
        !          2471:   if (ret < 0) 
        !          2472:     goto done;
        !          2473: 
        !          2474:   /* Get size and type again. */
        !          2475:   size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
        !          2476:   type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
        !          2477: 
        !          2478:   /* BGP packet dump function. */
        !          2479:   bgp_dump_packet (peer, type, peer->ibuf);
        !          2480:   
        !          2481:   size = (peer->packet_size - BGP_HEADER_SIZE);
        !          2482: 
        !          2483:   /* Read rest of the packet and call each sort of packet routine */
        !          2484:   switch (type) 
        !          2485:     {
        !          2486:     case BGP_MSG_OPEN:
        !          2487:       peer->open_in++;
        !          2488:       bgp_open_receive (peer, size); /* XXX return value ignored! */
        !          2489:       break;
        !          2490:     case BGP_MSG_UPDATE:
        !          2491:       peer->readtime = time(NULL);    /* Last read timer reset */
        !          2492:       bgp_update_receive (peer, size);
        !          2493:       break;
        !          2494:     case BGP_MSG_NOTIFY:
        !          2495:       bgp_notify_receive (peer, size);
        !          2496:       break;
        !          2497:     case BGP_MSG_KEEPALIVE:
        !          2498:       peer->readtime = time(NULL);    /* Last read timer reset */
        !          2499:       bgp_keepalive_receive (peer, size);
        !          2500:       break;
        !          2501:     case BGP_MSG_ROUTE_REFRESH_NEW:
        !          2502:     case BGP_MSG_ROUTE_REFRESH_OLD:
        !          2503:       peer->refresh_in++;
        !          2504:       bgp_route_refresh_receive (peer, size);
        !          2505:       break;
        !          2506:     case BGP_MSG_CAPABILITY:
        !          2507:       peer->dynamic_cap_in++;
        !          2508:       bgp_capability_receive (peer, size);
        !          2509:       break;
        !          2510:     }
        !          2511: 
        !          2512:   /* Clear input buffer. */
        !          2513:   peer->packet_size = 0;
        !          2514:   if (peer->ibuf)
        !          2515:     stream_reset (peer->ibuf);
        !          2516: 
        !          2517:  done:
        !          2518:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
        !          2519:     {
        !          2520:       if (BGP_DEBUG (events, EVENTS))
        !          2521:        zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
        !          2522:       peer_delete (peer);
        !          2523:     }
        !          2524:   return 0;
        !          2525: }

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