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

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

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