Annotation of embedaddon/bird2/proto/bgp/packets.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  *     BIRD -- BGP Packet Processing
        !             3:  *
        !             4:  *     (c) 2000 Martin Mares <mj@ucw.cz>
        !             5:  *     (c) 2008--2016 Ondrej Zajicek <santiago@crfreenet.org>
        !             6:  *     (c) 2008--2016 CZ.NIC z.s.p.o.
        !             7:  *
        !             8:  *     Can be freely distributed and used under the terms of the GNU GPL.
        !             9:  */
        !            10: 
        !            11: #undef LOCAL_DEBUG
        !            12: 
        !            13: #include <stdlib.h>
        !            14: 
        !            15: #include "nest/bird.h"
        !            16: #include "nest/iface.h"
        !            17: #include "nest/protocol.h"
        !            18: #include "nest/route.h"
        !            19: #include "nest/attrs.h"
        !            20: #include "proto/mrt/mrt.h"
        !            21: #include "conf/conf.h"
        !            22: #include "lib/unaligned.h"
        !            23: #include "lib/flowspec.h"
        !            24: #include "lib/socket.h"
        !            25: 
        !            26: #include "nest/cli.h"
        !            27: 
        !            28: #include "bgp.h"
        !            29: 
        !            30: 
        !            31: #define BGP_RR_REQUEST         0
        !            32: #define BGP_RR_BEGIN           1
        !            33: #define BGP_RR_END             2
        !            34: 
        !            35: #define BGP_NLRI_MAX           (4 + 1 + 32)
        !            36: 
        !            37: #define BGP_MPLS_BOS           1       /* Bottom-of-stack bit */
        !            38: #define BGP_MPLS_MAX           10      /* Max number of labels that 24*n <= 255 */
        !            39: #define BGP_MPLS_NULL          3       /* Implicit NULL label */
        !            40: #define BGP_MPLS_MAGIC         0x800000 /* Magic withdraw label value, RFC 3107 3 */
        !            41: 
        !            42: 
        !            43: static struct tbf rl_rcv_update = TBF_DEFAULT_LOG_LIMITS;
        !            44: static struct tbf rl_snd_update = TBF_DEFAULT_LOG_LIMITS;
        !            45: 
        !            46: /* Table for state -> RFC 6608 FSM error subcodes */
        !            47: static byte fsm_err_subcode[BS_MAX] = {
        !            48:   [BS_OPENSENT] = 1,
        !            49:   [BS_OPENCONFIRM] = 2,
        !            50:   [BS_ESTABLISHED] = 3
        !            51: };
        !            52: 
        !            53: 
        !            54: static struct bgp_channel *
        !            55: bgp_get_channel(struct bgp_proto *p, u32 afi)
        !            56: {
        !            57:   uint i;
        !            58: 
        !            59:   for (i = 0; i < p->channel_count; i++)
        !            60:     if (p->afi_map[i] == afi)
        !            61:       return p->channel_map[i];
        !            62: 
        !            63:   return NULL;
        !            64: }
        !            65: 
        !            66: static inline void
        !            67: put_af3(byte *buf, u32 id)
        !            68: {
        !            69:   put_u16(buf, id >> 16);
        !            70:   buf[2] = id & 0xff;
        !            71: }
        !            72: 
        !            73: static inline void
        !            74: put_af4(byte *buf, u32 id)
        !            75: {
        !            76:   put_u16(buf, id >> 16);
        !            77:   buf[2] = 0;
        !            78:   buf[3] = id & 0xff;
        !            79: }
        !            80: 
        !            81: static inline u32
        !            82: get_af3(byte *buf)
        !            83: {
        !            84:   return (get_u16(buf) << 16) | buf[2];
        !            85: }
        !            86: 
        !            87: static inline u32
        !            88: get_af4(byte *buf)
        !            89: {
        !            90:   return (get_u16(buf) << 16) | buf[3];
        !            91: }
        !            92: 
        !            93: static void
        !            94: init_mrt_bgp_data(struct bgp_conn *conn, struct mrt_bgp_data *d)
        !            95: {
        !            96:   struct bgp_proto *p = conn->bgp;
        !            97:   int p_ok = conn->state >= BS_OPENCONFIRM;
        !            98: 
        !            99:   memset(d, 0, sizeof(struct mrt_bgp_data));
        !           100:   d->peer_as = p->remote_as;
        !           101:   d->local_as = p->local_as;
        !           102:   d->index = (p->neigh && p->neigh->iface) ? p->neigh->iface->index : 0;
        !           103:   d->af = ipa_is_ip4(p->remote_ip) ? BGP_AFI_IPV4 : BGP_AFI_IPV6;
        !           104:   d->peer_ip = conn->sk ? conn->sk->daddr : IPA_NONE;
        !           105:   d->local_ip = conn->sk ? conn->sk->saddr : IPA_NONE;
        !           106:   d->as4 = p_ok ? p->as4_session : 0;
        !           107: }
        !           108: 
        !           109: static uint bgp_find_update_afi(byte *pos, uint len);
        !           110: 
        !           111: static int
        !           112: bgp_estimate_add_path(struct bgp_proto *p, byte *pkt, uint len)
        !           113: {
        !           114:   /* No need to estimate it for other messages than UPDATE */
        !           115:   if (pkt[18] != PKT_UPDATE)
        !           116:     return 0;
        !           117: 
        !           118:   /* 1 -> no channel, 2 -> all channels, 3 -> some channels */
        !           119:   if (p->summary_add_path_rx < 3)
        !           120:     return p->summary_add_path_rx == 2;
        !           121: 
        !           122:   uint afi = bgp_find_update_afi(pkt, len);
        !           123:   struct bgp_channel *c = bgp_get_channel(p, afi);
        !           124:   if (!c)
        !           125:   {
        !           126:     /* Either frame error (if !afi) or unknown AFI/SAFI,
        !           127:        will be reported later in regular parsing */
        !           128:     BGP_TRACE(D_PACKETS, "MRT processing noticed invalid packet");
        !           129:     return 0;
        !           130:   }
        !           131: 
        !           132:   return c->add_path_rx;
        !           133: }
        !           134: 
        !           135: static void
        !           136: bgp_dump_message(struct bgp_conn *conn, byte *pkt, uint len)
        !           137: {
        !           138:   struct mrt_bgp_data d;
        !           139:   init_mrt_bgp_data(conn, &d);
        !           140: 
        !           141:   d.message = pkt;
        !           142:   d.msg_len = len;
        !           143:   d.add_path = bgp_estimate_add_path(conn->bgp, pkt, len);
        !           144: 
        !           145:   mrt_dump_bgp_message(&d);
        !           146: }
        !           147: 
        !           148: void
        !           149: bgp_dump_state_change(struct bgp_conn *conn, uint old, uint new)
        !           150: {
        !           151:   struct mrt_bgp_data d;
        !           152:   init_mrt_bgp_data(conn, &d);
        !           153: 
        !           154:   d.old_state = old;
        !           155:   d.new_state = new;
        !           156: 
        !           157:   mrt_dump_bgp_state_change(&d);
        !           158: }
        !           159: 
        !           160: static byte *
        !           161: bgp_create_notification(struct bgp_conn *conn, byte *buf)
        !           162: {
        !           163:   struct bgp_proto *p = conn->bgp;
        !           164: 
        !           165:   BGP_TRACE(D_PACKETS, "Sending NOTIFICATION(code=%d.%d)", conn->notify_code, conn->notify_subcode);
        !           166:   buf[0] = conn->notify_code;
        !           167:   buf[1] = conn->notify_subcode;
        !           168:   memcpy(buf+2, conn->notify_data, conn->notify_size);
        !           169:   return buf + 2 + conn->notify_size;
        !           170: }
        !           171: 
        !           172: 
        !           173: /* Capability negotiation as per RFC 5492 */
        !           174: 
        !           175: const struct bgp_af_caps *
        !           176: bgp_find_af_caps(struct bgp_caps *caps, u32 afi)
        !           177: {
        !           178:   struct bgp_af_caps *ac;
        !           179: 
        !           180:   WALK_AF_CAPS(caps, ac)
        !           181:     if (ac->afi == afi)
        !           182:       return ac;
        !           183: 
        !           184:   return NULL;
        !           185: }
        !           186: 
        !           187: static struct bgp_af_caps *
        !           188: bgp_get_af_caps(struct bgp_caps **pcaps, u32 afi)
        !           189: {
        !           190:   struct bgp_caps *caps = *pcaps;
        !           191:   struct bgp_af_caps *ac;
        !           192: 
        !           193:   WALK_AF_CAPS(caps, ac)
        !           194:     if (ac->afi == afi)
        !           195:       return ac;
        !           196: 
        !           197:   uint n = caps->af_count;
        !           198:   if (uint_is_pow2(n))
        !           199:     *pcaps = caps = mb_realloc(caps, sizeof(struct bgp_caps) +
        !           200:                               (2 * n) * sizeof(struct bgp_af_caps));
        !           201: 
        !           202:   ac = &caps->af_data[caps->af_count++];
        !           203:   memset(ac, 0, sizeof(struct bgp_af_caps));
        !           204:   ac->afi = afi;
        !           205: 
        !           206:   return ac;
        !           207: }
        !           208: 
        !           209: static int
        !           210: bgp_af_caps_cmp(const void *X, const void *Y)
        !           211: {
        !           212:   const struct bgp_af_caps *x = X, *y = Y;
        !           213:   return (x->afi < y->afi) ? -1 : (x->afi > y->afi) ? 1 : 0;
        !           214: }
        !           215: 
        !           216: 
        !           217: void
        !           218: bgp_prepare_capabilities(struct bgp_conn *conn)
        !           219: {
        !           220:   struct bgp_proto *p = conn->bgp;
        !           221:   struct bgp_channel *c;
        !           222:   struct bgp_caps *caps;
        !           223:   struct bgp_af_caps *ac;
        !           224: 
        !           225:   if (!p->cf->capabilities)
        !           226:   {
        !           227:     /* Just prepare empty local_caps */
        !           228:     conn->local_caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps));
        !           229:     return;
        !           230:   }
        !           231: 
        !           232:   /* Prepare bgp_caps structure */
        !           233:   int n = list_length(&p->p.channels);
        !           234:   caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps) + n * sizeof(struct bgp_af_caps));
        !           235:   conn->local_caps = caps;
        !           236: 
        !           237:   caps->as4_support = p->cf->enable_as4;
        !           238:   caps->ext_messages = p->cf->enable_extended_messages;
        !           239:   caps->route_refresh = p->cf->enable_refresh;
        !           240:   caps->enhanced_refresh = p->cf->enable_refresh;
        !           241: 
        !           242:   if (caps->as4_support)
        !           243:     caps->as4_number = p->public_as;
        !           244: 
        !           245:   if (p->cf->gr_mode)
        !           246:   {
        !           247:     caps->gr_aware = 1;
        !           248:     caps->gr_time = p->cf->gr_time;
        !           249:     caps->gr_flags = p->p.gr_recovery ? BGP_GRF_RESTART : 0;
        !           250:   }
        !           251: 
        !           252:   if (p->cf->llgr_mode)
        !           253:     caps->llgr_aware = 1;
        !           254: 
        !           255:   /* Allocate and fill per-AF fields */
        !           256:   WALK_LIST(c, p->p.channels)
        !           257:   {
        !           258:     ac = &caps->af_data[caps->af_count++];
        !           259:     ac->afi = c->afi;
        !           260:     ac->ready = 1;
        !           261: 
        !           262:     ac->ext_next_hop = bgp_channel_is_ipv4(c) && c->cf->ext_next_hop;
        !           263:     caps->any_ext_next_hop |= ac->ext_next_hop;
        !           264: 
        !           265:     ac->add_path = c->cf->add_path;
        !           266:     caps->any_add_path |= ac->add_path;
        !           267: 
        !           268:     if (c->cf->gr_able)
        !           269:     {
        !           270:       ac->gr_able = 1;
        !           271: 
        !           272:       if (p->p.gr_recovery)
        !           273:        ac->gr_af_flags |= BGP_GRF_FORWARDING;
        !           274:     }
        !           275: 
        !           276:     if (c->cf->llgr_able)
        !           277:     {
        !           278:       ac->llgr_able = 1;
        !           279:       ac->llgr_time = c->cf->llgr_time;
        !           280: 
        !           281:       if (p->p.gr_recovery)
        !           282:        ac->llgr_flags |= BGP_LLGRF_FORWARDING;
        !           283:     }
        !           284:   }
        !           285: 
        !           286:   /* Sort capability fields by AFI/SAFI */
        !           287:   qsort(caps->af_data, caps->af_count, sizeof(struct bgp_af_caps), bgp_af_caps_cmp);
        !           288: }
        !           289: 
        !           290: static byte *
        !           291: bgp_write_capabilities(struct bgp_conn *conn, byte *buf)
        !           292: {
        !           293:   struct bgp_proto *p = conn->bgp;
        !           294:   struct bgp_caps *caps = conn->local_caps;
        !           295:   struct bgp_af_caps *ac;
        !           296:   byte *buf_head = buf;
        !           297:   byte *data;
        !           298: 
        !           299:   /* Create capability list in buffer */
        !           300: 
        !           301:   /*
        !           302:    * Note that max length is ~ 22+21*af_count. With max 12 channels that is
        !           303:    * 274. We are limited just by buffer size (4096, minus header), as we support
        !           304:    * extended optional parameres. Therefore, we have enough space for expansion.
        !           305:    */
        !           306: 
        !           307:   WALK_AF_CAPS(caps, ac)
        !           308:     if (ac->ready)
        !           309:     {
        !           310:       *buf++ = 1;              /* Capability 1: Multiprotocol extensions */
        !           311:       *buf++ = 4;              /* Capability data length */
        !           312:       put_af4(buf, ac->afi);
        !           313:       buf += 4;
        !           314:     }
        !           315: 
        !           316:   if (caps->route_refresh)
        !           317:   {
        !           318:     *buf++ = 2;                        /* Capability 2: Support for route refresh */
        !           319:     *buf++ = 0;                        /* Capability data length */
        !           320:   }
        !           321: 
        !           322:   if (caps->any_ext_next_hop)
        !           323:   {
        !           324:     *buf++ = 5;                        /* Capability 5: Support for extended next hop */
        !           325:     *buf++ = 0;                        /* Capability data length, will be fixed later */
        !           326:     data = buf;
        !           327: 
        !           328:     WALK_AF_CAPS(caps, ac)
        !           329:       if (ac->ext_next_hop)
        !           330:       {
        !           331:        put_af4(buf, ac->afi);
        !           332:        put_u16(buf+4, BGP_AFI_IPV6);
        !           333:        buf += 6;
        !           334:       }
        !           335: 
        !           336:     data[-1] = buf - data;
        !           337:   }
        !           338: 
        !           339:   if (caps->ext_messages)
        !           340:   {
        !           341:     *buf++ = 6;                        /* Capability 6: Support for extended messages */
        !           342:     *buf++ = 0;                        /* Capability data length */
        !           343:   }
        !           344: 
        !           345:   if (caps->gr_aware)
        !           346:   {
        !           347:     *buf++ = 64;               /* Capability 64: Support for graceful restart */
        !           348:     *buf++ = 0;                        /* Capability data length, will be fixed later */
        !           349:     data = buf;
        !           350: 
        !           351:     put_u16(buf, caps->gr_time);
        !           352:     buf[0] |= caps->gr_flags;
        !           353:     buf += 2;
        !           354: 
        !           355:     WALK_AF_CAPS(caps, ac)
        !           356:       if (ac->gr_able)
        !           357:       {
        !           358:        put_af3(buf, ac->afi);
        !           359:        buf[3] = ac->gr_af_flags;
        !           360:        buf += 4;
        !           361:       }
        !           362: 
        !           363:     data[-1] = buf - data;
        !           364:   }
        !           365: 
        !           366:   if (caps->as4_support)
        !           367:   {
        !           368:     *buf++ = 65;               /* Capability 65: Support for 4-octet AS number */
        !           369:     *buf++ = 4;                        /* Capability data length */
        !           370:     put_u32(buf, p->public_as);
        !           371:     buf += 4;
        !           372:   }
        !           373: 
        !           374:   if (caps->any_add_path)
        !           375:   {
        !           376:     *buf++ = 69;               /* Capability 69: Support for ADD-PATH */
        !           377:     *buf++ = 0;                        /* Capability data length, will be fixed later */
        !           378:     data = buf;
        !           379: 
        !           380:     WALK_AF_CAPS(caps, ac)
        !           381:       if (ac->add_path)
        !           382:       {
        !           383:        put_af3(buf, ac->afi);
        !           384:        buf[3] = ac->add_path;
        !           385:        buf += 4;
        !           386:       }
        !           387: 
        !           388:     data[-1] = buf - data;
        !           389:   }
        !           390: 
        !           391:   if (caps->enhanced_refresh)
        !           392:   {
        !           393:     *buf++ = 70;               /* Capability 70: Support for enhanced route refresh */
        !           394:     *buf++ = 0;                        /* Capability data length */
        !           395:   }
        !           396: 
        !           397:   if (caps->llgr_aware)
        !           398:   {
        !           399:     *buf++ = 71;               /* Capability 71: Support for long-lived graceful restart */
        !           400:     *buf++ = 0;                        /* Capability data length, will be fixed later */
        !           401:     data = buf;
        !           402: 
        !           403:     WALK_AF_CAPS(caps, ac)
        !           404:       if (ac->llgr_able)
        !           405:       {
        !           406:        put_af3(buf, ac->afi);
        !           407:        buf[3] = ac->llgr_flags;
        !           408:        put_u24(buf+4, ac->llgr_time);
        !           409:        buf += 7;
        !           410:       }
        !           411: 
        !           412:     data[-1] = buf - data;
        !           413:   }
        !           414: 
        !           415:   caps->length = buf - buf_head;
        !           416: 
        !           417:   return buf;
        !           418: }
        !           419: 
        !           420: static int
        !           421: bgp_read_capabilities(struct bgp_conn *conn, byte *pos, int len)
        !           422: {
        !           423:   struct bgp_proto *p = conn->bgp;
        !           424:   struct bgp_caps *caps;
        !           425:   struct bgp_af_caps *ac;
        !           426:   int i, cl;
        !           427:   u32 af;
        !           428: 
        !           429:   if (!conn->remote_caps)
        !           430:     caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps) + sizeof(struct bgp_af_caps));
        !           431:   else
        !           432:   {
        !           433:     caps = conn->remote_caps;
        !           434:     conn->remote_caps = NULL;
        !           435:   }
        !           436: 
        !           437:   caps->length += len;
        !           438: 
        !           439:   while (len > 0)
        !           440:   {
        !           441:     if (len < 2 || len < (2 + pos[1]))
        !           442:       goto err;
        !           443: 
        !           444:     /* Capability length */
        !           445:     cl = pos[1];
        !           446: 
        !           447:     /* Capability type */
        !           448:     switch (pos[0])
        !           449:     {
        !           450:     case  1: /* Multiprotocol capability, RFC 4760 */
        !           451:       if (cl != 4)
        !           452:        goto err;
        !           453: 
        !           454:       af = get_af4(pos+2);
        !           455:       ac = bgp_get_af_caps(&caps, af);
        !           456:       ac->ready = 1;
        !           457:       break;
        !           458: 
        !           459:     case  2: /* Route refresh capability, RFC 2918 */
        !           460:       if (cl != 0)
        !           461:        goto err;
        !           462: 
        !           463:       caps->route_refresh = 1;
        !           464:       break;
        !           465: 
        !           466:     case  5: /* Extended next hop encoding capability, RFC 5549 */
        !           467:       if (cl % 6)
        !           468:        goto err;
        !           469: 
        !           470:       for (i = 0; i < cl; i += 6)
        !           471:       {
        !           472:        /* Specified only for IPv4 prefixes with IPv6 next hops */
        !           473:        if ((get_u16(pos+2+i+0) != BGP_AFI_IPV4) ||
        !           474:            (get_u16(pos+2+i+4) != BGP_AFI_IPV6))
        !           475:          continue;
        !           476: 
        !           477:        af = get_af4(pos+2+i);
        !           478:        ac = bgp_get_af_caps(&caps, af);
        !           479:        ac->ext_next_hop = 1;
        !           480:       }
        !           481:       break;
        !           482: 
        !           483:     case  6: /* Extended message length capability, RFC draft */
        !           484:       if (cl != 0)
        !           485:        goto err;
        !           486: 
        !           487:       caps->ext_messages = 1;
        !           488:       break;
        !           489: 
        !           490:     case 64: /* Graceful restart capability, RFC 4724 */
        !           491:       if (cl % 4 != 2)
        !           492:        goto err;
        !           493: 
        !           494:       /* Only the last instance is valid */
        !           495:       WALK_AF_CAPS(caps, ac)
        !           496:       {
        !           497:        ac->gr_able = 0;
        !           498:        ac->gr_af_flags = 0;
        !           499:       }
        !           500: 
        !           501:       caps->gr_aware = 1;
        !           502:       caps->gr_flags = pos[2] & 0xf0;
        !           503:       caps->gr_time = get_u16(pos + 2) & 0x0fff;
        !           504: 
        !           505:       for (i = 2; i < cl; i += 4)
        !           506:       {
        !           507:        af = get_af3(pos+2+i);
        !           508:        ac = bgp_get_af_caps(&caps, af);
        !           509:        ac->gr_able = 1;
        !           510:        ac->gr_af_flags = pos[2+i+3];
        !           511:       }
        !           512:       break;
        !           513: 
        !           514:     case 65: /* AS4 capability, RFC 6793 */
        !           515:       if (cl != 4)
        !           516:        goto err;
        !           517: 
        !           518:       caps->as4_support = 1;
        !           519:       caps->as4_number = get_u32(pos + 2);
        !           520:       break;
        !           521: 
        !           522:     case 69: /* ADD-PATH capability, RFC 7911 */
        !           523:       if (cl % 4)
        !           524:        goto err;
        !           525: 
        !           526:       for (i = 0; i < cl; i += 4)
        !           527:       {
        !           528:        byte val = pos[2+i+3];
        !           529:        if (!val || (val > BGP_ADD_PATH_FULL))
        !           530:        {
        !           531:          log(L_WARN "%s: Got ADD-PATH capability with unknown value %u, ignoring",
        !           532:              p->p.name, val);
        !           533:          break;
        !           534:        }
        !           535:       }
        !           536: 
        !           537:       for (i = 0; i < cl; i += 4)
        !           538:       {
        !           539:        af = get_af3(pos+2+i);
        !           540:        ac = bgp_get_af_caps(&caps, af);
        !           541:        ac->add_path = pos[2+i+3];
        !           542:       }
        !           543:       break;
        !           544: 
        !           545:     case 70: /* Enhanced route refresh capability, RFC 7313 */
        !           546:       if (cl != 0)
        !           547:        goto err;
        !           548: 
        !           549:       caps->enhanced_refresh = 1;
        !           550:       break;
        !           551: 
        !           552:     case 71: /* Long lived graceful restart capability, RFC draft */
        !           553:       if (cl % 7)
        !           554:        goto err;
        !           555: 
        !           556:       /* Presumably, only the last instance is valid */
        !           557:       WALK_AF_CAPS(caps, ac)
        !           558:       {
        !           559:        ac->llgr_able = 0;
        !           560:        ac->llgr_flags = 0;
        !           561:        ac->llgr_time = 0;
        !           562:       }
        !           563: 
        !           564:       caps->llgr_aware = 1;
        !           565: 
        !           566:       for (i = 0; i < cl; i += 7)
        !           567:       {
        !           568:        af = get_af3(pos+2+i);
        !           569:        ac = bgp_get_af_caps(&caps, af);
        !           570:        ac->llgr_able = 1;
        !           571:        ac->llgr_flags = pos[2+i+3];
        !           572:        ac->llgr_time = get_u24(pos + 2+i+4);
        !           573:       }
        !           574:       break;
        !           575: 
        !           576:       /* We can safely ignore all other capabilities */
        !           577:     }
        !           578: 
        !           579:     ADVANCE(pos, len, 2 + cl);
        !           580:   }
        !           581: 
        !           582:   /* The LLGR capability must be advertised together with the GR capability,
        !           583:      otherwise it must be disregarded */
        !           584:   if (!caps->gr_aware && caps->llgr_aware)
        !           585:   {
        !           586:     caps->llgr_aware = 0;
        !           587:     WALK_AF_CAPS(caps, ac)
        !           588:     {
        !           589:       ac->llgr_able = 0;
        !           590:       ac->llgr_flags = 0;
        !           591:       ac->llgr_time = 0;
        !           592:     }
        !           593:   }
        !           594: 
        !           595:   conn->remote_caps = caps;
        !           596:   return 0;
        !           597: 
        !           598: err:
        !           599:   mb_free(caps);
        !           600:   bgp_error(conn, 2, 0, NULL, 0);
        !           601:   return -1;
        !           602: }
        !           603: 
        !           604: static int
        !           605: bgp_check_capabilities(struct bgp_conn *conn)
        !           606: {
        !           607:   struct bgp_proto *p = conn->bgp;
        !           608:   struct bgp_caps *local = conn->local_caps;
        !           609:   struct bgp_caps *remote = conn->remote_caps;
        !           610:   struct bgp_channel *c;
        !           611:   int count = 0;
        !           612: 
        !           613:   /* This is partially overlapping with bgp_conn_enter_established_state(),
        !           614:      but we need to run this just after we receive OPEN message */
        !           615: 
        !           616:   WALK_LIST(c, p->p.channels)
        !           617:   {
        !           618:     const struct bgp_af_caps *loc = bgp_find_af_caps(local,  c->afi);
        !           619:     const struct bgp_af_caps *rem = bgp_find_af_caps(remote, c->afi);
        !           620: 
        !           621:     /* Find out whether this channel will be active */
        !           622:     int active = loc && loc->ready &&
        !           623:       ((rem && rem->ready) || (!remote->length && (c->afi == BGP_AF_IPV4)));
        !           624: 
        !           625:     /* Mandatory must be active */
        !           626:     if (c->cf->mandatory && !active)
        !           627:       return 0;
        !           628: 
        !           629:     if (active)
        !           630:       count++;
        !           631:   }
        !           632: 
        !           633:   /* We need at least one channel active */
        !           634:   if (!count)
        !           635:     return 0;
        !           636: 
        !           637:   return 1;
        !           638: }
        !           639: 
        !           640: static int
        !           641: bgp_read_options(struct bgp_conn *conn, byte *pos, uint len, uint rest)
        !           642: {
        !           643:   struct bgp_proto *p = conn->bgp;
        !           644:   int ext = 0;
        !           645: 
        !           646:   /* Handle extended length (draft-ietf-idr-ext-opt-param-07) */
        !           647:   if ((len > 0) && (rest > 0) && (pos[0] == 255))
        !           648:   {
        !           649:     if (rest < 3)
        !           650:       goto err;
        !           651: 
        !           652:     /* Update pos/len to describe optional data */
        !           653:     len = get_u16(pos+1);
        !           654:     ext = 1;
        !           655:     pos += 3;
        !           656:     rest -= 3;
        !           657:   }
        !           658: 
        !           659:   /* Verify that optional data fits into OPEN packet */
        !           660:   if (len > rest)
        !           661:     goto err;
        !           662: 
        !           663:   /* Length of option parameter header */
        !           664:   uint hlen = ext ? 3 : 2;
        !           665: 
        !           666:   while (len > 0)
        !           667:   {
        !           668:     if (len < hlen)
        !           669:       goto err;
        !           670: 
        !           671:     uint otype = get_u8(pos);
        !           672:     uint olen = ext ? get_u16(pos+1) : get_u8(pos+1);
        !           673: 
        !           674:     if (len < (hlen + olen))
        !           675:       goto err;
        !           676: 
        !           677:     if (otype == 2)
        !           678:     {
        !           679:       /* BGP capabilities, RFC 5492 */
        !           680:       if (p->cf->capabilities)
        !           681:        if (bgp_read_capabilities(conn, pos + hlen, olen) < 0)
        !           682:          return -1;
        !           683:     }
        !           684:     else
        !           685:     {
        !           686:       /* Unknown option */
        !           687:       bgp_error(conn, 2, 4, pos, hlen + olen);
        !           688:       return -1;
        !           689:     }
        !           690: 
        !           691:     ADVANCE(pos, len, hlen + olen);
        !           692:   }
        !           693: 
        !           694:   /* Prepare empty caps if no capability option was announced */
        !           695:   if (!conn->remote_caps)
        !           696:     conn->remote_caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps));
        !           697: 
        !           698:   return 0;
        !           699: 
        !           700: err:
        !           701:   bgp_error(conn, 2, 0, NULL, 0);
        !           702:   return -1;
        !           703: }
        !           704: 
        !           705: static byte *
        !           706: bgp_create_open(struct bgp_conn *conn, byte *buf)
        !           707: {
        !           708:   struct bgp_proto *p = conn->bgp;
        !           709: 
        !           710:   BGP_TRACE(D_PACKETS, "Sending OPEN(ver=%d,as=%d,hold=%d,id=%08x)",
        !           711:            BGP_VERSION, p->public_as, p->cf->hold_time, p->local_id);
        !           712: 
        !           713:   buf[0] = BGP_VERSION;
        !           714:   put_u16(buf+1, (p->public_as < 0xFFFF) ? p->public_as : AS_TRANS);
        !           715:   put_u16(buf+3, p->cf->hold_time);
        !           716:   put_u32(buf+5, p->local_id);
        !           717: 
        !           718:   if (p->cf->capabilities)
        !           719:   {
        !           720:     /* Prepare local_caps and write capabilities to buffer */
        !           721:     byte *pos = buf+12;
        !           722:     byte *end = bgp_write_capabilities(conn, pos);
        !           723:     uint len = end - pos;
        !           724: 
        !           725:     if (len < 254)
        !           726:     {
        !           727:       buf[9] = len + 2;                /* Optional parameters length */
        !           728:       buf[10] = 2;             /* Option 2: Capability list */
        !           729:       buf[11] = len;           /* Option data length */
        !           730:     }
        !           731:     else /* draft-ietf-idr-ext-opt-param-07 */
        !           732:     {
        !           733:       /* Move capabilities 4 B forward */
        !           734:       memmove(buf + 16, pos, len);
        !           735:       pos = buf + 16;
        !           736:       end = pos + len;
        !           737: 
        !           738:       buf[9] = 255;            /* Non-ext OP length, fake */
        !           739:       buf[10] = 255;           /* Non-ext OP type, signals extended length */
        !           740:       put_u16(buf+11, len + 3);        /* Extended optional parameters length */
        !           741:       buf[13] = 2;             /* Option 2: Capability list */
        !           742:       put_u16(buf+14, len);    /* Option extended data length */
        !           743:     }
        !           744: 
        !           745:     return end;
        !           746:   }
        !           747:   else
        !           748:   {
        !           749:     buf[9] = 0;                        /* No optional parameters */
        !           750:     return buf + 10;
        !           751:   }
        !           752: 
        !           753:   return buf;
        !           754: }
        !           755: 
        !           756: static void
        !           757: bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
        !           758: {
        !           759:   struct bgp_proto *p = conn->bgp;
        !           760:   struct bgp_conn *other;
        !           761:   u32 asn, hold, id;
        !           762: 
        !           763:   /* Check state */
        !           764:   if (conn->state != BS_OPENSENT)
        !           765:   { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
        !           766: 
        !           767:   /* Check message length */
        !           768:   if (len < 29)
        !           769:   { bgp_error(conn, 1, 2, pkt+16, 2); return; }
        !           770: 
        !           771:   if (pkt[19] != BGP_VERSION)
        !           772:   { u16 val = BGP_VERSION; bgp_error(conn, 2, 1, (byte *) &val, 2); return; }
        !           773: 
        !           774:   asn = get_u16(pkt+20);
        !           775:   hold = get_u16(pkt+22);
        !           776:   id = get_u32(pkt+24);
        !           777:   BGP_TRACE(D_PACKETS, "Got OPEN(as=%d,hold=%d,id=%R)", asn, hold, id);
        !           778: 
        !           779:   if (bgp_read_options(conn, pkt+29, pkt[28], len-29) < 0)
        !           780:     return;
        !           781: 
        !           782:   if (hold > 0 && hold < 3)
        !           783:   { bgp_error(conn, 2, 6, pkt+22, 2); return; }
        !           784: 
        !           785:   /* RFC 6286 2.2 - router ID is nonzero and AS-wide unique */
        !           786:   if (!id || (p->is_internal && id == p->local_id))
        !           787:   { bgp_error(conn, 2, 3, pkt+24, -4); return; }
        !           788: 
        !           789:   /* RFC 5492 4 - check for required capabilities */
        !           790:   if (p->cf->capabilities && !bgp_check_capabilities(conn))
        !           791:   { bgp_error(conn, 2, 7, NULL, 0); return; }
        !           792: 
        !           793:   struct bgp_caps *caps = conn->remote_caps;
        !           794: 
        !           795:   if (caps->as4_support)
        !           796:   {
        !           797:     u32 as4 = caps->as4_number;
        !           798: 
        !           799:     if ((as4 != asn) && (asn != AS_TRANS))
        !           800:       log(L_WARN "%s: Peer advertised inconsistent AS numbers", p->p.name);
        !           801: 
        !           802:     /* When remote ASN is unspecified, it must be external one */
        !           803:     if (p->remote_as ? (as4 != p->remote_as) : (as4 == p->local_as))
        !           804:     { as4 = htonl(as4); bgp_error(conn, 2, 2, (byte *) &as4, 4); return; }
        !           805: 
        !           806:     conn->received_as = as4;
        !           807:   }
        !           808:   else
        !           809:   {
        !           810:     if (p->remote_as ? (asn != p->remote_as) : (asn == p->local_as))
        !           811:     { bgp_error(conn, 2, 2, pkt+20, 2); return; }
        !           812: 
        !           813:     conn->received_as = asn;
        !           814:   }
        !           815: 
        !           816:   /* Check the other connection */
        !           817:   other = (conn == &p->outgoing_conn) ? &p->incoming_conn : &p->outgoing_conn;
        !           818:   switch (other->state)
        !           819:   {
        !           820:   case BS_CONNECT:
        !           821:   case BS_ACTIVE:
        !           822:     /* Stop outgoing connection attempts */
        !           823:     bgp_conn_enter_idle_state(other);
        !           824:     break;
        !           825: 
        !           826:   case BS_IDLE:
        !           827:   case BS_OPENSENT:
        !           828:   case BS_CLOSE:
        !           829:     break;
        !           830: 
        !           831:   case BS_OPENCONFIRM:
        !           832:     /*
        !           833:      * Description of collision detection rules in RFC 4271 is confusing and
        !           834:      * contradictory, but it is essentially:
        !           835:      *
        !           836:      * 1. Router with higher ID is dominant
        !           837:      * 2. If both have the same ID, router with higher ASN is dominant [RFC6286]
        !           838:      * 3. When both connections are in OpenConfirm state, one initiated by
        !           839:      *    the dominant router is kept.
        !           840:      *
        !           841:      * The first line in the expression below evaluates whether the neighbor
        !           842:      * is dominant, the second line whether the new connection was initiated
        !           843:      * by the neighbor. If both are true (or both are false), we keep the new
        !           844:      * connection, otherwise we keep the old one.
        !           845:      */
        !           846:     if (((p->local_id < id) || ((p->local_id == id) && (p->public_as < p->remote_as)))
        !           847:        == (conn == &p->incoming_conn))
        !           848:     {
        !           849:       /* Should close the other connection */
        !           850:       BGP_TRACE(D_EVENTS, "Connection collision, giving up the other connection");
        !           851:       bgp_error(other, 6, 7, NULL, 0);
        !           852:       break;
        !           853:     }
        !           854:     /* Fall thru */
        !           855:   case BS_ESTABLISHED:
        !           856:     /* Should close this connection */
        !           857:     BGP_TRACE(D_EVENTS, "Connection collision, giving up this connection");
        !           858:     bgp_error(conn, 6, 7, NULL, 0);
        !           859:     return;
        !           860: 
        !           861:   default:
        !           862:     bug("bgp_rx_open: Unknown state");
        !           863:   }
        !           864: 
        !           865:   /* Update our local variables */
        !           866:   conn->hold_time = MIN(hold, p->cf->hold_time);
        !           867:   conn->keepalive_time = p->cf->keepalive_time ? : conn->hold_time / 3;
        !           868:   conn->as4_session = conn->local_caps->as4_support && caps->as4_support;
        !           869:   conn->ext_messages = conn->local_caps->ext_messages && caps->ext_messages;
        !           870:   p->remote_id = id;
        !           871: 
        !           872:   DBG("BGP: Hold timer set to %d, keepalive to %d, AS to %d, ID to %x, AS4 session to %d\n",
        !           873:       conn->hold_time, conn->keepalive_time, p->remote_as, p->remote_id, conn->as4_session);
        !           874: 
        !           875:   bgp_schedule_packet(conn, NULL, PKT_KEEPALIVE);
        !           876:   bgp_start_timer(conn->hold_timer, conn->hold_time);
        !           877:   bgp_conn_enter_openconfirm_state(conn);
        !           878: }
        !           879: 
        !           880: 
        !           881: /*
        !           882:  *     Next hop handling
        !           883:  */
        !           884: 
        !           885: #define REPORT(msg, args...) \
        !           886:   ({ log(L_REMOTE "%s: " msg, s->proto->p.name, ## args); })
        !           887: 
        !           888: #define DISCARD(msg, args...) \
        !           889:   ({ REPORT(msg, ## args); return; })
        !           890: 
        !           891: #define WITHDRAW(msg, args...) \
        !           892:   ({ REPORT(msg, ## args); s->err_withdraw = 1; return; })
        !           893: 
        !           894: #define BAD_AFI                "Unexpected AF <%u/%u> in UPDATE"
        !           895: #define BAD_NEXT_HOP   "Invalid NEXT_HOP attribute"
        !           896: #define NO_NEXT_HOP    "Missing NEXT_HOP attribute"
        !           897: #define NO_LABEL_STACK "Missing MPLS stack"
        !           898: 
        !           899: 
        !           900: static void
        !           901: bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll)
        !           902: {
        !           903:   struct bgp_proto *p = s->proto;
        !           904:   struct bgp_channel *c = s->channel;
        !           905: 
        !           906:   if (c->cf->gw_mode == GW_DIRECT)
        !           907:   {
        !           908:     neighbor *nbr = NULL;
        !           909: 
        !           910:     /* GW_DIRECT -> single_hop -> p->neigh != NULL */
        !           911:     if (ipa_nonzero(gw))
        !           912:       nbr = neigh_find(&p->p, gw, NULL, 0);
        !           913:     else if (ipa_nonzero(ll))
        !           914:       nbr = neigh_find(&p->p, ll, p->neigh->iface, 0);
        !           915: 
        !           916:     if (!nbr || (nbr->scope == SCOPE_HOST))
        !           917:       WITHDRAW(BAD_NEXT_HOP);
        !           918: 
        !           919:     a->dest = RTD_UNICAST;
        !           920:     a->nh.gw = nbr->addr;
        !           921:     a->nh.iface = nbr->iface;
        !           922:     a->igp_metric = c->cf->cost;
        !           923:   }
        !           924:   else /* GW_RECURSIVE */
        !           925:   {
        !           926:     if (ipa_zero(gw))
        !           927:       WITHDRAW(BAD_NEXT_HOP);
        !           928: 
        !           929:     rtable *tab = ipa_is_ip4(gw) ? c->igp_table_ip4 : c->igp_table_ip6;
        !           930:     s->hostentry = rt_get_hostentry(tab, gw, ll, c->c.table);
        !           931: 
        !           932:     if (!s->mpls)
        !           933:       rta_apply_hostentry(a, s->hostentry, NULL);
        !           934: 
        !           935:     /* With MPLS, hostentry is applied later in bgp_apply_mpls_labels() */
        !           936:   }
        !           937: }
        !           938: 
        !           939: static void
        !           940: bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 *labels, uint lnum)
        !           941: {
        !           942:   if (lnum > MPLS_MAX_LABEL_STACK)
        !           943:   {
        !           944:     REPORT("Too many MPLS labels ($u)", lnum);
        !           945: 
        !           946:     a->dest = RTD_UNREACHABLE;
        !           947:     a->hostentry = NULL;
        !           948:     a->nh = (struct nexthop) { };
        !           949:     return;
        !           950:   }
        !           951: 
        !           952:   /* Handle implicit NULL as empty MPLS stack */
        !           953:   if ((lnum == 1) && (labels[0] == BGP_MPLS_NULL))
        !           954:     lnum = 0;
        !           955: 
        !           956:   if (s->channel->cf->gw_mode == GW_DIRECT)
        !           957:   {
        !           958:     a->nh.labels = lnum;
        !           959:     memcpy(a->nh.label, labels, 4*lnum);
        !           960:   }
        !           961:   else /* GW_RECURSIVE */
        !           962:   {
        !           963:     mpls_label_stack ms;
        !           964: 
        !           965:     ms.len = lnum;
        !           966:     memcpy(ms.stack, labels, 4*lnum);
        !           967:     rta_apply_hostentry(a, s->hostentry, &ms);
        !           968:   }
        !           969: }
        !           970: 
        !           971: 
        !           972: static int
        !           973: bgp_match_src(struct bgp_export_state *s, int mode)
        !           974: {
        !           975:   switch (mode)
        !           976:   {
        !           977:   case NH_NO:          return 0;
        !           978:   case NH_ALL:         return 1;
        !           979:   case NH_IBGP:                return s->src && s->src->is_internal;
        !           980:   case NH_EBGP:                return s->src && !s->src->is_internal;
        !           981:   default:             return 0;
        !           982:   }
        !           983: }
        !           984: 
        !           985: static inline int
        !           986: bgp_use_next_hop(struct bgp_export_state *s, eattr *a)
        !           987: {
        !           988:   struct bgp_proto *p = s->proto;
        !           989:   struct bgp_channel *c = s->channel;
        !           990:   ip_addr *nh = (void *) a->u.ptr->data;
        !           991: 
        !           992:   /* Handle next hop self option */
        !           993:   if (c->cf->next_hop_self && bgp_match_src(s, c->cf->next_hop_self))
        !           994:     return 0;
        !           995: 
        !           996:   /* Handle next hop keep option */
        !           997:   if (c->cf->next_hop_keep && bgp_match_src(s, c->cf->next_hop_keep))
        !           998:     return 1;
        !           999: 
        !          1000:   /* Keep it when explicitly set in export filter */
        !          1001:   if (a->type & EAF_FRESH)
        !          1002:     return 1;
        !          1003: 
        !          1004:   /* Check for non-matching AF */
        !          1005:   if ((ipa_is_ip4(*nh) != bgp_channel_is_ipv4(c)) && !c->ext_next_hop)
        !          1006:     return 0;
        !          1007: 
        !          1008:   /* Keep it when exported to internal peers */
        !          1009:   if (p->is_interior && ipa_nonzero(*nh))
        !          1010:     return 1;
        !          1011: 
        !          1012:   /* Keep it when forwarded between single-hop BGPs on the same iface */
        !          1013:   struct iface *ifa = (s->src && s->src->neigh) ? s->src->neigh->iface : NULL;
        !          1014:   return p->neigh && (p->neigh->iface == ifa);
        !          1015: }
        !          1016: 
        !          1017: static inline int
        !          1018: bgp_use_gateway(struct bgp_export_state *s)
        !          1019: {
        !          1020:   struct bgp_proto *p = s->proto;
        !          1021:   struct bgp_channel *c = s->channel;
        !          1022:   rta *ra = s->route->attrs;
        !          1023: 
        !          1024:   /* Handle next hop self option - also applies to gateway */
        !          1025:   if (c->cf->next_hop_self && bgp_match_src(s, c->cf->next_hop_self))
        !          1026:     return 0;
        !          1027: 
        !          1028:   /* We need one valid global gateway */
        !          1029:   if ((ra->dest != RTD_UNICAST) || ra->nh.next || ipa_zero(ra->nh.gw) || ipa_is_link_local(ra->nh.gw))
        !          1030:     return 0;
        !          1031: 
        !          1032:   /* Check for non-matching AF */
        !          1033:   if ((ipa_is_ip4(ra->nh.gw) != bgp_channel_is_ipv4(c)) && !c->ext_next_hop)
        !          1034:     return 0;
        !          1035: 
        !          1036:   /* Use it when exported to internal peers */
        !          1037:   if (p->is_interior)
        !          1038:     return 1;
        !          1039: 
        !          1040:   /* Use it when forwarded to single-hop BGP peer on on the same iface */
        !          1041:   return p->neigh && (p->neigh->iface == ra->nh.iface);
        !          1042: }
        !          1043: 
        !          1044: static void
        !          1045: bgp_update_next_hop_ip(struct bgp_export_state *s, eattr *a, ea_list **to)
        !          1046: {
        !          1047:   if (!a || !bgp_use_next_hop(s, a))
        !          1048:   {
        !          1049:     if (bgp_use_gateway(s))
        !          1050:     {
        !          1051:       rta *ra = s->route->attrs;
        !          1052:       ip_addr nh[1] = { ra->nh.gw };
        !          1053:       bgp_set_attr_data(to, s->pool, BA_NEXT_HOP, 0, nh, 16);
        !          1054: 
        !          1055:       if (s->mpls)
        !          1056:       {
        !          1057:        u32 implicit_null = BGP_MPLS_NULL;
        !          1058:        u32 *labels = ra->nh.labels ? ra->nh.label : &implicit_null;
        !          1059:        uint lnum = ra->nh.labels ? ra->nh.labels : 1;
        !          1060:        bgp_set_attr_data(to, s->pool, BA_MPLS_LABEL_STACK, 0, labels, lnum * 4);
        !          1061:       }
        !          1062:     }
        !          1063:     else
        !          1064:     {
        !          1065:       ip_addr nh[2] = { s->channel->next_hop_addr, s->channel->link_addr };
        !          1066:       bgp_set_attr_data(to, s->pool, BA_NEXT_HOP, 0, nh, ipa_nonzero(nh[1]) ? 32 : 16);
        !          1067:       s->local_next_hop = 1;
        !          1068: 
        !          1069:       /* TODO: Use local MPLS assigned label */
        !          1070:       if (s->mpls)
        !          1071:       {
        !          1072:        u32 implicit_null = BGP_MPLS_NULL;
        !          1073:        bgp_set_attr_data(to, s->pool, BA_MPLS_LABEL_STACK, 0, &implicit_null, 4);
        !          1074:       }
        !          1075:     }
        !          1076:   }
        !          1077: 
        !          1078:   /* Check if next hop is valid */
        !          1079:   a = bgp_find_attr(*to, BA_NEXT_HOP);
        !          1080:   if (!a)
        !          1081:     WITHDRAW(NO_NEXT_HOP);
        !          1082: 
        !          1083:   ip_addr *nh = (void *) a->u.ptr->data;
        !          1084:   ip_addr peer = s->proto->remote_ip;
        !          1085:   uint len = a->u.ptr->length;
        !          1086: 
        !          1087:   /* Forbid zero next hop */
        !          1088:   if (ipa_zero(nh[0]) && ((len != 32) || ipa_zero(nh[1])))
        !          1089:     WITHDRAW(BAD_NEXT_HOP);
        !          1090: 
        !          1091:   /* Forbid next hop equal to neighbor IP */
        !          1092:   if (ipa_equal(peer, nh[0]) || ((len == 32) && ipa_equal(peer, nh[1])))
        !          1093:     WITHDRAW(BAD_NEXT_HOP);
        !          1094: 
        !          1095:   /* Forbid next hop with non-matching AF */
        !          1096:   if ((ipa_is_ip4(nh[0]) != bgp_channel_is_ipv4(s->channel)) &&
        !          1097:       !s->channel->ext_next_hop)
        !          1098:     WITHDRAW(BAD_NEXT_HOP);
        !          1099: 
        !          1100:   /* Just check if MPLS stack */
        !          1101:   if (s->mpls && !bgp_find_attr(*to, BA_MPLS_LABEL_STACK))
        !          1102:     WITHDRAW(NO_LABEL_STACK);
        !          1103: }
        !          1104: 
        !          1105: static uint
        !          1106: bgp_encode_next_hop_ip(struct bgp_write_state *s, eattr *a, byte *buf, uint size UNUSED)
        !          1107: {
        !          1108:   /* This function is used only for MP-BGP, see bgp_encode_next_hop() for IPv4 BGP */
        !          1109:   ip_addr *nh = (void *) a->u.ptr->data;
        !          1110:   uint len = a->u.ptr->length;
        !          1111: 
        !          1112:   ASSERT((len == 16) || (len == 32));
        !          1113: 
        !          1114:   /*
        !          1115:    * Both IPv4 and IPv6 next hops can be used (with ext_next_hop enabled). This
        !          1116:    * is specified in RFC 5549 for IPv4 and in RFC 4798 for IPv6. The difference
        !          1117:    * is that IPv4 address is directly encoded with IPv4 NLRI, but as IPv4-mapped
        !          1118:    * IPv6 address with IPv6 NLRI.
        !          1119:    */
        !          1120: 
        !          1121:   if (bgp_channel_is_ipv4(s->channel) && ipa_is_ip4(nh[0]))
        !          1122:   {
        !          1123:     put_ip4(buf, ipa_to_ip4(nh[0]));
        !          1124:     return 4;
        !          1125:   }
        !          1126: 
        !          1127:   put_ip6(buf, ipa_to_ip6(nh[0]));
        !          1128: 
        !          1129:   if (len == 32)
        !          1130:     put_ip6(buf+16, ipa_to_ip6(nh[1]));
        !          1131: 
        !          1132:   return len;
        !          1133: }
        !          1134: 
        !          1135: static void
        !          1136: bgp_decode_next_hop_ip(struct bgp_parse_state *s, byte *data, uint len, rta *a)
        !          1137: {
        !          1138:   struct bgp_channel *c = s->channel;
        !          1139:   struct adata *ad = lp_alloc_adata(s->pool, 32);
        !          1140:   ip_addr *nh = (void *) ad->data;
        !          1141: 
        !          1142:   if (len == 4)
        !          1143:   {
        !          1144:     nh[0] = ipa_from_ip4(get_ip4(data));
        !          1145:     nh[1] = IPA_NONE;
        !          1146:   }
        !          1147:   else if (len == 16)
        !          1148:   {
        !          1149:     nh[0] = ipa_from_ip6(get_ip6(data));
        !          1150:     nh[1] = IPA_NONE;
        !          1151: 
        !          1152:     if (ipa_is_link_local(nh[0]))
        !          1153:     { nh[1] = nh[0]; nh[0] = IPA_NONE; }
        !          1154:   }
        !          1155:   else if (len == 32)
        !          1156:   {
        !          1157:     nh[0] = ipa_from_ip6(get_ip6(data));
        !          1158:     nh[1] = ipa_from_ip6(get_ip6(data+16));
        !          1159: 
        !          1160:     if (ipa_is_ip4(nh[0]) || !ip6_is_link_local(nh[1]))
        !          1161:       nh[1] = IPA_NONE;
        !          1162:   }
        !          1163:   else
        !          1164:     bgp_parse_error(s, 9);
        !          1165: 
        !          1166:   if (ipa_zero(nh[1]))
        !          1167:     ad->length = 16;
        !          1168: 
        !          1169:   if ((bgp_channel_is_ipv4(c) != ipa_is_ip4(nh[0])) && !c->ext_next_hop)
        !          1170:     WITHDRAW(BAD_NEXT_HOP);
        !          1171: 
        !          1172:   // XXXX validate next hop
        !          1173: 
        !          1174:   bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_NEXT_HOP, 0, ad);
        !          1175:   bgp_apply_next_hop(s, a, nh[0], nh[1]);
        !          1176: }
        !          1177: 
        !          1178: static uint
        !          1179: bgp_encode_next_hop_vpn(struct bgp_write_state *s, eattr *a, byte *buf, uint size UNUSED)
        !          1180: {
        !          1181:   ip_addr *nh = (void *) a->u.ptr->data;
        !          1182:   uint len = a->u.ptr->length;
        !          1183: 
        !          1184:   ASSERT((len == 16) || (len == 32));
        !          1185: 
        !          1186:   /*
        !          1187:    * Both IPv4 and IPv6 next hops can be used (with ext_next_hop enabled). This
        !          1188:    * is specified in RFC 5549 for VPNv4 and in RFC 4659 for VPNv6. The difference
        !          1189:    * is that IPv4 address is directly encoded with VPNv4 NLRI, but as IPv4-mapped
        !          1190:    * IPv6 address with VPNv6 NLRI.
        !          1191:    */
        !          1192: 
        !          1193:   if (bgp_channel_is_ipv4(s->channel) && ipa_is_ip4(nh[0]))
        !          1194:   {
        !          1195:     put_u64(buf, 0); /* VPN RD is 0 */
        !          1196:     put_ip4(buf+8, ipa_to_ip4(nh[0]));
        !          1197:     return 12;
        !          1198:   }
        !          1199: 
        !          1200:   put_u64(buf, 0); /* VPN RD is 0 */
        !          1201:   put_ip6(buf+8, ipa_to_ip6(nh[0]));
        !          1202: 
        !          1203:   if (len == 16)
        !          1204:     return 24;
        !          1205: 
        !          1206:   put_u64(buf+24, 0); /* VPN RD is 0 */
        !          1207:   put_ip6(buf+32, ipa_to_ip6(nh[1]));
        !          1208: 
        !          1209:   return 48;
        !          1210: }
        !          1211: 
        !          1212: static void
        !          1213: bgp_decode_next_hop_vpn(struct bgp_parse_state *s, byte *data, uint len, rta *a)
        !          1214: {
        !          1215:   struct bgp_channel *c = s->channel;
        !          1216:   struct adata *ad = lp_alloc_adata(s->pool, 32);
        !          1217:   ip_addr *nh = (void *) ad->data;
        !          1218: 
        !          1219:   if (len == 12)
        !          1220:   {
        !          1221:     nh[0] = ipa_from_ip4(get_ip4(data+8));
        !          1222:     nh[1] = IPA_NONE;
        !          1223:   }
        !          1224:   else if (len == 24)
        !          1225:   {
        !          1226:     nh[0] = ipa_from_ip6(get_ip6(data+8));
        !          1227:     nh[1] = IPA_NONE;
        !          1228: 
        !          1229:     if (ipa_is_link_local(nh[0]))
        !          1230:     { nh[1] = nh[0]; nh[0] = IPA_NONE; }
        !          1231:   }
        !          1232:   else if (len == 48)
        !          1233:   {
        !          1234:     nh[0] = ipa_from_ip6(get_ip6(data+8));
        !          1235:     nh[1] = ipa_from_ip6(get_ip6(data+32));
        !          1236: 
        !          1237:     if (ipa_is_ip4(nh[0]) || !ip6_is_link_local(nh[1]))
        !          1238:       nh[1] = IPA_NONE;
        !          1239:   }
        !          1240:   else
        !          1241:     bgp_parse_error(s, 9);
        !          1242: 
        !          1243:   if (ipa_zero(nh[1]))
        !          1244:     ad->length = 16;
        !          1245: 
        !          1246:   /* XXXX which error */
        !          1247:   if ((get_u64(data) != 0) || ((len == 48) && (get_u64(data+24) != 0)))
        !          1248:     bgp_parse_error(s, 9);
        !          1249: 
        !          1250:   if ((bgp_channel_is_ipv4(c) != ipa_is_ip4(nh[0])) && !c->ext_next_hop)
        !          1251:     WITHDRAW(BAD_NEXT_HOP);
        !          1252: 
        !          1253:   // XXXX validate next hop
        !          1254: 
        !          1255:   bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_NEXT_HOP, 0, ad);
        !          1256:   bgp_apply_next_hop(s, a, nh[0], nh[1]);
        !          1257: }
        !          1258: 
        !          1259: 
        !          1260: 
        !          1261: static uint
        !          1262: bgp_encode_next_hop_none(struct bgp_write_state *s UNUSED, eattr *a UNUSED, byte *buf UNUSED, uint size UNUSED)
        !          1263: {
        !          1264:   return 0;
        !          1265: }
        !          1266: 
        !          1267: static void
        !          1268: bgp_decode_next_hop_none(struct bgp_parse_state *s UNUSED, byte *data UNUSED, uint len UNUSED, rta *a UNUSED)
        !          1269: {
        !          1270:   /*
        !          1271:    * Although we expect no next hop and RFC 7606 7.11 states that attribute
        !          1272:    * MP_REACH_NLRI with unexpected next hop length is considered malformed,
        !          1273:    * FlowSpec RFC 5575 4 states that next hop shall be ignored on receipt.
        !          1274:    */
        !          1275: 
        !          1276:   return;
        !          1277: }
        !          1278: 
        !          1279: static void
        !          1280: bgp_update_next_hop_none(struct bgp_export_state *s, eattr *a, ea_list **to)
        !          1281: {
        !          1282:   /* NEXT_HOP shall not pass */
        !          1283:   if (a)
        !          1284:     bgp_unset_attr(to, s->pool, BA_NEXT_HOP);
        !          1285: }
        !          1286: 
        !          1287: 
        !          1288: /*
        !          1289:  *     UPDATE
        !          1290:  */
        !          1291: 
        !          1292: static void
        !          1293: bgp_rte_update(struct bgp_parse_state *s, net_addr *n, u32 path_id, rta *a0)
        !          1294: {
        !          1295:   if (path_id != s->last_id)
        !          1296:   {
        !          1297:     s->last_src = rt_get_source(&s->proto->p, path_id);
        !          1298:     s->last_id = path_id;
        !          1299: 
        !          1300:     rta_free(s->cached_rta);
        !          1301:     s->cached_rta = NULL;
        !          1302:   }
        !          1303: 
        !          1304:   if (!a0)
        !          1305:   {
        !          1306:     /* Route withdraw */
        !          1307:     rte_update3(&s->channel->c, n, NULL, s->last_src);
        !          1308:     return;
        !          1309:   }
        !          1310: 
        !          1311:   /* Prepare cached route attributes */
        !          1312:   if (s->cached_rta == NULL)
        !          1313:   {
        !          1314:     a0->src = s->last_src;
        !          1315: 
        !          1316:     /* Workaround for rta_lookup() breaking eattrs */
        !          1317:     ea_list *ea = a0->eattrs;
        !          1318:     s->cached_rta = rta_lookup(a0);
        !          1319:     a0->eattrs = ea;
        !          1320:   }
        !          1321: 
        !          1322:   rta *a = rta_clone(s->cached_rta);
        !          1323:   rte *e = rte_get_temp(a);
        !          1324: 
        !          1325:   e->pflags = 0;
        !          1326:   e->u.bgp.suppressed = 0;
        !          1327:   e->u.bgp.stale = -1;
        !          1328:   rte_update3(&s->channel->c, n, e, s->last_src);
        !          1329: }
        !          1330: 
        !          1331: static void
        !          1332: bgp_encode_mpls_labels(struct bgp_write_state *s UNUSED, const adata *mpls, byte **pos, uint *size, byte *pxlen)
        !          1333: {
        !          1334:   const u32 dummy = 0;
        !          1335:   const u32 *labels = mpls ? (const u32 *) mpls->data : &dummy;
        !          1336:   uint lnum = mpls ? (mpls->length / 4) : 1;
        !          1337: 
        !          1338:   for (uint i = 0; i < lnum; i++)
        !          1339:   {
        !          1340:     put_u24(*pos, labels[i] << 4);
        !          1341:     ADVANCE(*pos, *size, 3);
        !          1342:   }
        !          1343: 
        !          1344:   /* Add bottom-of-stack flag */
        !          1345:   (*pos)[-1] |= BGP_MPLS_BOS;
        !          1346: 
        !          1347:   *pxlen += 24 * lnum;
        !          1348: }
        !          1349: 
        !          1350: static void
        !          1351: bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *pxlen, rta *a)
        !          1352: {
        !          1353:   u32 labels[BGP_MPLS_MAX], label;
        !          1354:   uint lnum = 0;
        !          1355: 
        !          1356:   do {
        !          1357:     if (*pxlen < 24)
        !          1358:       bgp_parse_error(s, 1);
        !          1359: 
        !          1360:     label = get_u24(*pos);
        !          1361:     labels[lnum++] = label >> 4;
        !          1362:     ADVANCE(*pos, *len, 3);
        !          1363:     *pxlen -= 24;
        !          1364: 
        !          1365:     /* RFC 8277 2.4 - withdraw does not have variable-size MPLS stack but
        !          1366:        fixed-size 24-bit Compatibility field, which MUST be ignored */
        !          1367:     if (!a && !s->err_withdraw)
        !          1368:       return;
        !          1369:   }
        !          1370:   while (!(label & BGP_MPLS_BOS));
        !          1371: 
        !          1372:   if (!a)
        !          1373:     return;
        !          1374: 
        !          1375:   /* Attach MPLS attribute unless we already have one */
        !          1376:   if (!s->mpls_labels)
        !          1377:   {
        !          1378:     s->mpls_labels = lp_alloc_adata(s->pool, 4*BGP_MPLS_MAX);
        !          1379:     bgp_set_attr_ptr(&(a->eattrs), s->pool, BA_MPLS_LABEL_STACK, 0, s->mpls_labels);
        !          1380:   }
        !          1381: 
        !          1382:   /* Overwrite data in the attribute */
        !          1383:   s->mpls_labels->length = 4*lnum;
        !          1384:   memcpy(s->mpls_labels->data, labels, 4*lnum);
        !          1385: 
        !          1386:   /* Update next hop entry in rta */
        !          1387:   bgp_apply_mpls_labels(s, a, labels, lnum);
        !          1388: 
        !          1389:   /* Attributes were changed, invalidate cached entry */
        !          1390:   rta_free(s->cached_rta);
        !          1391:   s->cached_rta = NULL;
        !          1392: 
        !          1393:   return;
        !          1394: }
        !          1395: 
        !          1396: static uint
        !          1397: bgp_encode_nlri_ip4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
        !          1398: {
        !          1399:   byte *pos = buf;
        !          1400: 
        !          1401:   while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
        !          1402:   {
        !          1403:     struct bgp_prefix *px = HEAD(buck->prefixes);
        !          1404:     struct net_addr_ip4 *net = (void *) px->net;
        !          1405: 
        !          1406:     /* Encode path ID */
        !          1407:     if (s->add_path)
        !          1408:     {
        !          1409:       put_u32(pos, px->path_id);
        !          1410:       ADVANCE(pos, size, 4);
        !          1411:     }
        !          1412: 
        !          1413:     /* Encode prefix length */
        !          1414:     *pos = net->pxlen;
        !          1415:     ADVANCE(pos, size, 1);
        !          1416: 
        !          1417:     /* Encode MPLS labels */
        !          1418:     if (s->mpls)
        !          1419:       bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
        !          1420: 
        !          1421:     /* Encode prefix body */
        !          1422:     ip4_addr a = ip4_hton(net->prefix);
        !          1423:     uint b = (net->pxlen + 7) / 8;
        !          1424:     memcpy(pos, &a, b);
        !          1425:     ADVANCE(pos, size, b);
        !          1426: 
        !          1427:     bgp_free_prefix(s->channel, px);
        !          1428:   }
        !          1429: 
        !          1430:   return pos - buf;
        !          1431: }
        !          1432: 
        !          1433: static void
        !          1434: bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
        !          1435: {
        !          1436:   while (len)
        !          1437:   {
        !          1438:     net_addr_ip4 net;
        !          1439:     u32 path_id = 0;
        !          1440: 
        !          1441:     /* Decode path ID */
        !          1442:     if (s->add_path)
        !          1443:     {
        !          1444:       if (len < 5)
        !          1445:        bgp_parse_error(s, 1);
        !          1446: 
        !          1447:       path_id = get_u32(pos);
        !          1448:       ADVANCE(pos, len, 4);
        !          1449:     }
        !          1450: 
        !          1451:     /* Decode prefix length */
        !          1452:     uint l = *pos;
        !          1453:     ADVANCE(pos, len, 1);
        !          1454: 
        !          1455:     if (len < ((l + 7) / 8))
        !          1456:       bgp_parse_error(s, 1);
        !          1457: 
        !          1458:     /* Decode MPLS labels */
        !          1459:     if (s->mpls)
        !          1460:       bgp_decode_mpls_labels(s, &pos, &len, &l, a);
        !          1461: 
        !          1462:     if (l > IP4_MAX_PREFIX_LENGTH)
        !          1463:       bgp_parse_error(s, 10);
        !          1464: 
        !          1465:     /* Decode prefix body */
        !          1466:     ip4_addr addr = IP4_NONE;
        !          1467:     uint b = (l + 7) / 8;
        !          1468:     memcpy(&addr, pos, b);
        !          1469:     ADVANCE(pos, len, b);
        !          1470: 
        !          1471:     net = NET_ADDR_IP4(ip4_ntoh(addr), l);
        !          1472:     net_normalize_ip4(&net);
        !          1473: 
        !          1474:     // XXXX validate prefix
        !          1475: 
        !          1476:     bgp_rte_update(s, (net_addr *) &net, path_id, a);
        !          1477:   }
        !          1478: }
        !          1479: 
        !          1480: 
        !          1481: static uint
        !          1482: bgp_encode_nlri_ip6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
        !          1483: {
        !          1484:   byte *pos = buf;
        !          1485: 
        !          1486:   while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
        !          1487:   {
        !          1488:     struct bgp_prefix *px = HEAD(buck->prefixes);
        !          1489:     struct net_addr_ip6 *net = (void *) px->net;
        !          1490: 
        !          1491:     /* Encode path ID */
        !          1492:     if (s->add_path)
        !          1493:     {
        !          1494:       put_u32(pos, px->path_id);
        !          1495:       ADVANCE(pos, size, 4);
        !          1496:     }
        !          1497: 
        !          1498:     /* Encode prefix length */
        !          1499:     *pos = net->pxlen;
        !          1500:     ADVANCE(pos, size, 1);
        !          1501: 
        !          1502:     /* Encode MPLS labels */
        !          1503:     if (s->mpls)
        !          1504:       bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
        !          1505: 
        !          1506:     /* Encode prefix body */
        !          1507:     ip6_addr a = ip6_hton(net->prefix);
        !          1508:     uint b = (net->pxlen + 7) / 8;
        !          1509:     memcpy(pos, &a, b);
        !          1510:     ADVANCE(pos, size, b);
        !          1511: 
        !          1512:     bgp_free_prefix(s->channel, px);
        !          1513:   }
        !          1514: 
        !          1515:   return pos - buf;
        !          1516: }
        !          1517: 
        !          1518: static void
        !          1519: bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
        !          1520: {
        !          1521:   while (len)
        !          1522:   {
        !          1523:     net_addr_ip6 net;
        !          1524:     u32 path_id = 0;
        !          1525: 
        !          1526:     /* Decode path ID */
        !          1527:     if (s->add_path)
        !          1528:     {
        !          1529:       if (len < 5)
        !          1530:        bgp_parse_error(s, 1);
        !          1531: 
        !          1532:       path_id = get_u32(pos);
        !          1533:       ADVANCE(pos, len, 4);
        !          1534:     }
        !          1535: 
        !          1536:     /* Decode prefix length */
        !          1537:     uint l = *pos;
        !          1538:     ADVANCE(pos, len, 1);
        !          1539: 
        !          1540:     if (len < ((l + 7) / 8))
        !          1541:       bgp_parse_error(s, 1);
        !          1542: 
        !          1543:     /* Decode MPLS labels */
        !          1544:     if (s->mpls)
        !          1545:       bgp_decode_mpls_labels(s, &pos, &len, &l, a);
        !          1546: 
        !          1547:     if (l > IP6_MAX_PREFIX_LENGTH)
        !          1548:       bgp_parse_error(s, 10);
        !          1549: 
        !          1550:     /* Decode prefix body */
        !          1551:     ip6_addr addr = IP6_NONE;
        !          1552:     uint b = (l + 7) / 8;
        !          1553:     memcpy(&addr, pos, b);
        !          1554:     ADVANCE(pos, len, b);
        !          1555: 
        !          1556:     net = NET_ADDR_IP6(ip6_ntoh(addr), l);
        !          1557:     net_normalize_ip6(&net);
        !          1558: 
        !          1559:     // XXXX validate prefix
        !          1560: 
        !          1561:     bgp_rte_update(s, (net_addr *) &net, path_id, a);
        !          1562:   }
        !          1563: }
        !          1564: 
        !          1565: static uint
        !          1566: bgp_encode_nlri_vpn4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
        !          1567: {
        !          1568:   byte *pos = buf;
        !          1569: 
        !          1570:   while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
        !          1571:   {
        !          1572:     struct bgp_prefix *px = HEAD(buck->prefixes);
        !          1573:     struct net_addr_vpn4 *net = (void *) px->net;
        !          1574: 
        !          1575:     /* Encode path ID */
        !          1576:     if (s->add_path)
        !          1577:     {
        !          1578:       put_u32(pos, px->path_id);
        !          1579:       ADVANCE(pos, size, 4);
        !          1580:     }
        !          1581: 
        !          1582:     /* Encode prefix length */
        !          1583:     *pos = 64 + net->pxlen;
        !          1584:     ADVANCE(pos, size, 1);
        !          1585: 
        !          1586:     /* Encode MPLS labels */
        !          1587:     if (s->mpls)
        !          1588:       bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
        !          1589: 
        !          1590:     /* Encode route distinguisher */
        !          1591:     put_u64(pos, net->rd);
        !          1592:     ADVANCE(pos, size, 8);
        !          1593: 
        !          1594:     /* Encode prefix body */
        !          1595:     ip4_addr a = ip4_hton(net->prefix);
        !          1596:     uint b = (net->pxlen + 7) / 8;
        !          1597:     memcpy(pos, &a, b);
        !          1598:     ADVANCE(pos, size, b);
        !          1599: 
        !          1600:     bgp_free_prefix(s->channel, px);
        !          1601:   }
        !          1602: 
        !          1603:   return pos - buf;
        !          1604: }
        !          1605: 
        !          1606: static void
        !          1607: bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
        !          1608: {
        !          1609:   while (len)
        !          1610:   {
        !          1611:     net_addr_vpn4 net;
        !          1612:     u32 path_id = 0;
        !          1613: 
        !          1614:     /* Decode path ID */
        !          1615:     if (s->add_path)
        !          1616:     {
        !          1617:       if (len < 5)
        !          1618:        bgp_parse_error(s, 1);
        !          1619: 
        !          1620:       path_id = get_u32(pos);
        !          1621:       ADVANCE(pos, len, 4);
        !          1622:     }
        !          1623: 
        !          1624:     /* Decode prefix length */
        !          1625:     uint l = *pos;
        !          1626:     ADVANCE(pos, len, 1);
        !          1627: 
        !          1628:     if (len < ((l + 7) / 8))
        !          1629:       bgp_parse_error(s, 1);
        !          1630: 
        !          1631:     /* Decode MPLS labels */
        !          1632:     if (s->mpls)
        !          1633:       bgp_decode_mpls_labels(s, &pos, &len, &l, a);
        !          1634: 
        !          1635:     /* Decode route distinguisher */
        !          1636:     if (l < 64)
        !          1637:       bgp_parse_error(s, 1);
        !          1638: 
        !          1639:     u64 rd = get_u64(pos);
        !          1640:     ADVANCE(pos, len, 8);
        !          1641:     l -= 64;
        !          1642: 
        !          1643:     if (l > IP4_MAX_PREFIX_LENGTH)
        !          1644:       bgp_parse_error(s, 10);
        !          1645: 
        !          1646:     /* Decode prefix body */
        !          1647:     ip4_addr addr = IP4_NONE;
        !          1648:     uint b = (l + 7) / 8;
        !          1649:     memcpy(&addr, pos, b);
        !          1650:     ADVANCE(pos, len, b);
        !          1651: 
        !          1652:     net = NET_ADDR_VPN4(ip4_ntoh(addr), l, rd);
        !          1653:     net_normalize_vpn4(&net);
        !          1654: 
        !          1655:     // XXXX validate prefix
        !          1656: 
        !          1657:     bgp_rte_update(s, (net_addr *) &net, path_id, a);
        !          1658:   }
        !          1659: }
        !          1660: 
        !          1661: 
        !          1662: static uint
        !          1663: bgp_encode_nlri_vpn6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
        !          1664: {
        !          1665:   byte *pos = buf;
        !          1666: 
        !          1667:   while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
        !          1668:   {
        !          1669:     struct bgp_prefix *px = HEAD(buck->prefixes);
        !          1670:     struct net_addr_vpn6 *net = (void *) px->net;
        !          1671: 
        !          1672:     /* Encode path ID */
        !          1673:     if (s->add_path)
        !          1674:     {
        !          1675:       put_u32(pos, px->path_id);
        !          1676:       ADVANCE(pos, size, 4);
        !          1677:     }
        !          1678: 
        !          1679:     /* Encode prefix length */
        !          1680:     *pos = 64 + net->pxlen;
        !          1681:     ADVANCE(pos, size, 1);
        !          1682: 
        !          1683:     /* Encode MPLS labels */
        !          1684:     if (s->mpls)
        !          1685:       bgp_encode_mpls_labels(s, s->mpls_labels, &pos, &size, pos - 1);
        !          1686: 
        !          1687:     /* Encode route distinguisher */
        !          1688:     put_u64(pos, net->rd);
        !          1689:     ADVANCE(pos, size, 8);
        !          1690: 
        !          1691:     /* Encode prefix body */
        !          1692:     ip6_addr a = ip6_hton(net->prefix);
        !          1693:     uint b = (net->pxlen + 7) / 8;
        !          1694:     memcpy(pos, &a, b);
        !          1695:     ADVANCE(pos, size, b);
        !          1696: 
        !          1697:     bgp_free_prefix(s->channel, px);
        !          1698:   }
        !          1699: 
        !          1700:   return pos - buf;
        !          1701: }
        !          1702: 
        !          1703: static void
        !          1704: bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
        !          1705: {
        !          1706:   while (len)
        !          1707:   {
        !          1708:     net_addr_vpn6 net;
        !          1709:     u32 path_id = 0;
        !          1710: 
        !          1711:     /* Decode path ID */
        !          1712:     if (s->add_path)
        !          1713:     {
        !          1714:       if (len < 5)
        !          1715:        bgp_parse_error(s, 1);
        !          1716: 
        !          1717:       path_id = get_u32(pos);
        !          1718:       ADVANCE(pos, len, 4);
        !          1719:     }
        !          1720: 
        !          1721:     /* Decode prefix length */
        !          1722:     uint l = *pos;
        !          1723:     ADVANCE(pos, len, 1);
        !          1724: 
        !          1725:     if (len < ((l + 7) / 8))
        !          1726:       bgp_parse_error(s, 1);
        !          1727: 
        !          1728:     /* Decode MPLS labels */
        !          1729:     if (s->mpls)
        !          1730:       bgp_decode_mpls_labels(s, &pos, &len, &l, a);
        !          1731: 
        !          1732:     /* Decode route distinguisher */
        !          1733:     if (l < 64)
        !          1734:       bgp_parse_error(s, 1);
        !          1735: 
        !          1736:     u64 rd = get_u64(pos);
        !          1737:     ADVANCE(pos, len, 8);
        !          1738:     l -= 64;
        !          1739: 
        !          1740:     if (l > IP6_MAX_PREFIX_LENGTH)
        !          1741:       bgp_parse_error(s, 10);
        !          1742: 
        !          1743:     /* Decode prefix body */
        !          1744:     ip6_addr addr = IP6_NONE;
        !          1745:     uint b = (l + 7) / 8;
        !          1746:     memcpy(&addr, pos, b);
        !          1747:     ADVANCE(pos, len, b);
        !          1748: 
        !          1749:     net = NET_ADDR_VPN6(ip6_ntoh(addr), l, rd);
        !          1750:     net_normalize_vpn6(&net);
        !          1751: 
        !          1752:     // XXXX validate prefix
        !          1753: 
        !          1754:     bgp_rte_update(s, (net_addr *) &net, path_id, a);
        !          1755:   }
        !          1756: }
        !          1757: 
        !          1758: 
        !          1759: static uint
        !          1760: bgp_encode_nlri_flow4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
        !          1761: {
        !          1762:   byte *pos = buf;
        !          1763: 
        !          1764:   while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
        !          1765:   {
        !          1766:     struct bgp_prefix *px = HEAD(buck->prefixes);
        !          1767:     struct net_addr_flow4 *net = (void *) px->net;
        !          1768:     uint flen = net->length - sizeof(net_addr_flow4);
        !          1769: 
        !          1770:     /* Encode path ID */
        !          1771:     if (s->add_path)
        !          1772:     {
        !          1773:       put_u32(pos, px->path_id);
        !          1774:       ADVANCE(pos, size, 4);
        !          1775:     }
        !          1776: 
        !          1777:     if (flen > size)
        !          1778:       break;
        !          1779: 
        !          1780:     /* Copy whole flow data including length */
        !          1781:     memcpy(pos, net->data, flen);
        !          1782:     ADVANCE(pos, size, flen);
        !          1783: 
        !          1784:     bgp_free_prefix(s->channel, px);
        !          1785:   }
        !          1786: 
        !          1787:   return pos - buf;
        !          1788: }
        !          1789: 
        !          1790: static void
        !          1791: bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
        !          1792: {
        !          1793:   while (len)
        !          1794:   {
        !          1795:     u32 path_id = 0;
        !          1796: 
        !          1797:     /* Decode path ID */
        !          1798:     if (s->add_path)
        !          1799:     {
        !          1800:       if (len < 4)
        !          1801:        bgp_parse_error(s, 1);
        !          1802: 
        !          1803:       path_id = get_u32(pos);
        !          1804:       ADVANCE(pos, len, 4);
        !          1805:     }
        !          1806: 
        !          1807:     if (len < 2)
        !          1808:       bgp_parse_error(s, 1);
        !          1809: 
        !          1810:     /* Decode flow length */
        !          1811:     uint hlen = flow_hdr_length(pos);
        !          1812:     uint dlen = flow_read_length(pos);
        !          1813:     uint flen = hlen + dlen;
        !          1814:     byte *data = pos + hlen;
        !          1815: 
        !          1816:     if (len < flen)
        !          1817:       bgp_parse_error(s, 1);
        !          1818: 
        !          1819:     /* Validate flow data */
        !          1820:     enum flow_validated_state r = flow4_validate(data, dlen);
        !          1821:     if (r != FLOW_ST_VALID)
        !          1822:     {
        !          1823:       log(L_REMOTE "%s: Invalid flow route: %s", s->proto->p.name, flow_validated_state_str(r));
        !          1824:       bgp_parse_error(s, 1);
        !          1825:     }
        !          1826: 
        !          1827:     if (data[0] != FLOW_TYPE_DST_PREFIX)
        !          1828:     {
        !          1829:       log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
        !          1830:       bgp_parse_error(s, 1);
        !          1831:     }
        !          1832: 
        !          1833:     /* Decode dst prefix */
        !          1834:     ip4_addr px = IP4_NONE;
        !          1835:     uint pxlen = data[1];
        !          1836: 
        !          1837:     // FIXME: Use some generic function
        !          1838:     memcpy(&px, data+2, BYTES(pxlen));
        !          1839:     px = ip4_and(ip4_ntoh(px), ip4_mkmask(pxlen));
        !          1840: 
        !          1841:     /* Prepare the flow */
        !          1842:     net_addr *n = alloca(sizeof(struct net_addr_flow4) + flen);
        !          1843:     net_fill_flow4(n, px, pxlen, pos, flen);
        !          1844:     ADVANCE(pos, len, flen);
        !          1845: 
        !          1846:     bgp_rte_update(s, n, path_id, a);
        !          1847:   }
        !          1848: }
        !          1849: 
        !          1850: 
        !          1851: static uint
        !          1852: bgp_encode_nlri_flow6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size)
        !          1853: {
        !          1854:   byte *pos = buf;
        !          1855: 
        !          1856:   while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
        !          1857:   {
        !          1858:     struct bgp_prefix *px = HEAD(buck->prefixes);
        !          1859:     struct net_addr_flow6 *net = (void *) px->net;
        !          1860:     uint flen = net->length - sizeof(net_addr_flow6);
        !          1861: 
        !          1862:     /* Encode path ID */
        !          1863:     if (s->add_path)
        !          1864:     {
        !          1865:       put_u32(pos, px->path_id);
        !          1866:       ADVANCE(pos, size, 4);
        !          1867:     }
        !          1868: 
        !          1869:     if (flen > size)
        !          1870:       break;
        !          1871: 
        !          1872:     /* Copy whole flow data including length */
        !          1873:     memcpy(pos, net->data, flen);
        !          1874:     ADVANCE(pos, size, flen);
        !          1875: 
        !          1876:     bgp_free_prefix(s->channel, px);
        !          1877:   }
        !          1878: 
        !          1879:   return pos - buf;
        !          1880: }
        !          1881: 
        !          1882: static void
        !          1883: bgp_decode_nlri_flow6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
        !          1884: {
        !          1885:   while (len)
        !          1886:   {
        !          1887:     u32 path_id = 0;
        !          1888: 
        !          1889:     /* Decode path ID */
        !          1890:     if (s->add_path)
        !          1891:     {
        !          1892:       if (len < 4)
        !          1893:        bgp_parse_error(s, 1);
        !          1894: 
        !          1895:       path_id = get_u32(pos);
        !          1896:       ADVANCE(pos, len, 4);
        !          1897:     }
        !          1898: 
        !          1899:     if (len < 2)
        !          1900:       bgp_parse_error(s, 1);
        !          1901: 
        !          1902:     /* Decode flow length */
        !          1903:     uint hlen = flow_hdr_length(pos);
        !          1904:     uint dlen = flow_read_length(pos);
        !          1905:     uint flen = hlen + dlen;
        !          1906:     byte *data = pos + hlen;
        !          1907: 
        !          1908:     if (len < flen)
        !          1909:       bgp_parse_error(s, 1);
        !          1910: 
        !          1911:     /* Validate flow data */
        !          1912:     enum flow_validated_state r = flow6_validate(data, dlen);
        !          1913:     if (r != FLOW_ST_VALID)
        !          1914:     {
        !          1915:       log(L_REMOTE "%s: Invalid flow route: %s", s->proto->p.name, flow_validated_state_str(r));
        !          1916:       bgp_parse_error(s, 1);
        !          1917:     }
        !          1918: 
        !          1919:     if (data[0] != FLOW_TYPE_DST_PREFIX)
        !          1920:     {
        !          1921:       log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
        !          1922:       bgp_parse_error(s, 1);
        !          1923:     }
        !          1924: 
        !          1925:     /* Decode dst prefix */
        !          1926:     ip6_addr px = IP6_NONE;
        !          1927:     uint pxlen = data[1];
        !          1928: 
        !          1929:     // FIXME: Use some generic function
        !          1930:     memcpy(&px, data+2, BYTES(pxlen));
        !          1931:     px = ip6_and(ip6_ntoh(px), ip6_mkmask(pxlen));
        !          1932: 
        !          1933:     /* Prepare the flow */
        !          1934:     net_addr *n = alloca(sizeof(struct net_addr_flow6) + flen);
        !          1935:     net_fill_flow6(n, px, pxlen, pos, flen);
        !          1936:     ADVANCE(pos, len, flen);
        !          1937: 
        !          1938:     bgp_rte_update(s, n, path_id, a);
        !          1939:   }
        !          1940: }
        !          1941: 
        !          1942: 
        !          1943: static const struct bgp_af_desc bgp_af_table[] = {
        !          1944:   {
        !          1945:     .afi = BGP_AF_IPV4,
        !          1946:     .net = NET_IP4,
        !          1947:     .name = "ipv4",
        !          1948:     .encode_nlri = bgp_encode_nlri_ip4,
        !          1949:     .decode_nlri = bgp_decode_nlri_ip4,
        !          1950:     .encode_next_hop = bgp_encode_next_hop_ip,
        !          1951:     .decode_next_hop = bgp_decode_next_hop_ip,
        !          1952:     .update_next_hop = bgp_update_next_hop_ip,
        !          1953:   },
        !          1954:   {
        !          1955:     .afi = BGP_AF_IPV4_MC,
        !          1956:     .net = NET_IP4,
        !          1957:     .name = "ipv4-mc",
        !          1958:     .encode_nlri = bgp_encode_nlri_ip4,
        !          1959:     .decode_nlri = bgp_decode_nlri_ip4,
        !          1960:     .encode_next_hop = bgp_encode_next_hop_ip,
        !          1961:     .decode_next_hop = bgp_decode_next_hop_ip,
        !          1962:     .update_next_hop = bgp_update_next_hop_ip,
        !          1963:   },
        !          1964:   {
        !          1965:     .afi = BGP_AF_IPV4_MPLS,
        !          1966:     .net = NET_IP4,
        !          1967:     .mpls = 1,
        !          1968:     .name = "ipv4-mpls",
        !          1969:     .encode_nlri = bgp_encode_nlri_ip4,
        !          1970:     .decode_nlri = bgp_decode_nlri_ip4,
        !          1971:     .encode_next_hop = bgp_encode_next_hop_ip,
        !          1972:     .decode_next_hop = bgp_decode_next_hop_ip,
        !          1973:     .update_next_hop = bgp_update_next_hop_ip,
        !          1974:   },
        !          1975:   {
        !          1976:     .afi = BGP_AF_IPV6,
        !          1977:     .net = NET_IP6,
        !          1978:     .name = "ipv6",
        !          1979:     .encode_nlri = bgp_encode_nlri_ip6,
        !          1980:     .decode_nlri = bgp_decode_nlri_ip6,
        !          1981:     .encode_next_hop = bgp_encode_next_hop_ip,
        !          1982:     .decode_next_hop = bgp_decode_next_hop_ip,
        !          1983:     .update_next_hop = bgp_update_next_hop_ip,
        !          1984:   },
        !          1985:   {
        !          1986:     .afi = BGP_AF_IPV6_MC,
        !          1987:     .net = NET_IP6,
        !          1988:     .name = "ipv6-mc",
        !          1989:     .encode_nlri = bgp_encode_nlri_ip6,
        !          1990:     .decode_nlri = bgp_decode_nlri_ip6,
        !          1991:     .encode_next_hop = bgp_encode_next_hop_ip,
        !          1992:     .decode_next_hop = bgp_decode_next_hop_ip,
        !          1993:     .update_next_hop = bgp_update_next_hop_ip,
        !          1994:   },
        !          1995:   {
        !          1996:     .afi = BGP_AF_IPV6_MPLS,
        !          1997:     .net = NET_IP6,
        !          1998:     .mpls = 1,
        !          1999:     .name = "ipv6-mpls",
        !          2000:     .encode_nlri = bgp_encode_nlri_ip6,
        !          2001:     .decode_nlri = bgp_decode_nlri_ip6,
        !          2002:     .encode_next_hop = bgp_encode_next_hop_ip,
        !          2003:     .decode_next_hop = bgp_decode_next_hop_ip,
        !          2004:     .update_next_hop = bgp_update_next_hop_ip,
        !          2005:   },
        !          2006:   {
        !          2007:     .afi = BGP_AF_VPN4_MPLS,
        !          2008:     .net = NET_VPN4,
        !          2009:     .mpls = 1,
        !          2010:     .name = "vpn4-mpls",
        !          2011:     .encode_nlri = bgp_encode_nlri_vpn4,
        !          2012:     .decode_nlri = bgp_decode_nlri_vpn4,
        !          2013:     .encode_next_hop = bgp_encode_next_hop_vpn,
        !          2014:     .decode_next_hop = bgp_decode_next_hop_vpn,
        !          2015:     .update_next_hop = bgp_update_next_hop_ip,
        !          2016:   },
        !          2017:   {
        !          2018:     .afi = BGP_AF_VPN6_MPLS,
        !          2019:     .net = NET_VPN6,
        !          2020:     .mpls = 1,
        !          2021:     .name = "vpn6-mpls",
        !          2022:     .encode_nlri = bgp_encode_nlri_vpn6,
        !          2023:     .decode_nlri = bgp_decode_nlri_vpn6,
        !          2024:     .encode_next_hop = bgp_encode_next_hop_vpn,
        !          2025:     .decode_next_hop = bgp_decode_next_hop_vpn,
        !          2026:     .update_next_hop = bgp_update_next_hop_ip,
        !          2027:   },
        !          2028:   {
        !          2029:     .afi = BGP_AF_VPN4_MC,
        !          2030:     .net = NET_VPN4,
        !          2031:     .name = "vpn4-mc",
        !          2032:     .encode_nlri = bgp_encode_nlri_vpn4,
        !          2033:     .decode_nlri = bgp_decode_nlri_vpn4,
        !          2034:     .encode_next_hop = bgp_encode_next_hop_vpn,
        !          2035:     .decode_next_hop = bgp_decode_next_hop_vpn,
        !          2036:     .update_next_hop = bgp_update_next_hop_ip,
        !          2037:   },
        !          2038:   {
        !          2039:     .afi = BGP_AF_VPN6_MC,
        !          2040:     .net = NET_VPN6,
        !          2041:     .name = "vpn6-mc",
        !          2042:     .encode_nlri = bgp_encode_nlri_vpn6,
        !          2043:     .decode_nlri = bgp_decode_nlri_vpn6,
        !          2044:     .encode_next_hop = bgp_encode_next_hop_vpn,
        !          2045:     .decode_next_hop = bgp_decode_next_hop_vpn,
        !          2046:     .update_next_hop = bgp_update_next_hop_ip,
        !          2047:   },
        !          2048:   {
        !          2049:     .afi = BGP_AF_FLOW4,
        !          2050:     .net = NET_FLOW4,
        !          2051:     .no_igp = 1,
        !          2052:     .name = "flow4",
        !          2053:     .encode_nlri = bgp_encode_nlri_flow4,
        !          2054:     .decode_nlri = bgp_decode_nlri_flow4,
        !          2055:     .encode_next_hop = bgp_encode_next_hop_none,
        !          2056:     .decode_next_hop = bgp_decode_next_hop_none,
        !          2057:     .update_next_hop = bgp_update_next_hop_none,
        !          2058:   },
        !          2059:   {
        !          2060:     .afi = BGP_AF_FLOW6,
        !          2061:     .net = NET_FLOW6,
        !          2062:     .no_igp = 1,
        !          2063:     .name = "flow6",
        !          2064:     .encode_nlri = bgp_encode_nlri_flow6,
        !          2065:     .decode_nlri = bgp_decode_nlri_flow6,
        !          2066:     .encode_next_hop = bgp_encode_next_hop_none,
        !          2067:     .decode_next_hop = bgp_decode_next_hop_none,
        !          2068:     .update_next_hop = bgp_update_next_hop_none,
        !          2069:   },
        !          2070: };
        !          2071: 
        !          2072: const struct bgp_af_desc *
        !          2073: bgp_get_af_desc(u32 afi)
        !          2074: {
        !          2075:   uint i;
        !          2076:   for (i = 0; i < ARRAY_SIZE(bgp_af_table); i++)
        !          2077:     if (bgp_af_table[i].afi == afi)
        !          2078:       return &bgp_af_table[i];
        !          2079: 
        !          2080:   return NULL;
        !          2081: }
        !          2082: 
        !          2083: static inline uint
        !          2084: bgp_encode_nlri(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
        !          2085: {
        !          2086:   return s->channel->desc->encode_nlri(s, buck, buf, end - buf);
        !          2087: }
        !          2088: 
        !          2089: static inline uint
        !          2090: bgp_encode_next_hop(struct bgp_write_state *s, eattr *nh, byte *buf)
        !          2091: {
        !          2092:   return s->channel->desc->encode_next_hop(s, nh, buf, 255);
        !          2093: }
        !          2094: 
        !          2095: void
        !          2096: bgp_update_next_hop(struct bgp_export_state *s, eattr *a, ea_list **to)
        !          2097: {
        !          2098:   s->channel->desc->update_next_hop(s, a, to);
        !          2099: }
        !          2100: 
        !          2101: #define MAX_ATTRS_LENGTH (end-buf+BGP_HEADER_LENGTH - 1024)
        !          2102: 
        !          2103: static byte *
        !          2104: bgp_create_ip_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
        !          2105: {
        !          2106:   /*
        !          2107:    *   2 B     Withdrawn Routes Length (zero)
        !          2108:    *   ---     IPv4 Withdrawn Routes NLRI (unused)
        !          2109:    *   2 B     Total Path Attribute Length
        !          2110:    *   var     Path Attributes
        !          2111:    *   var     IPv4 Network Layer Reachability Information
        !          2112:    */
        !          2113: 
        !          2114:   int lr, la;
        !          2115: 
        !          2116:   la = bgp_encode_attrs(s, buck->eattrs, buf+4, buf + MAX_ATTRS_LENGTH);
        !          2117:   if (la < 0)
        !          2118:   {
        !          2119:     /* Attribute list too long */
        !          2120:     bgp_withdraw_bucket(s->channel, buck);
        !          2121:     return NULL;
        !          2122:   }
        !          2123: 
        !          2124:   put_u16(buf+0, 0);
        !          2125:   put_u16(buf+2, la);
        !          2126: 
        !          2127:   lr = bgp_encode_nlri(s, buck, buf+4+la, end);
        !          2128: 
        !          2129:   return buf+4+la+lr;
        !          2130: }
        !          2131: 
        !          2132: static byte *
        !          2133: bgp_create_mp_reach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
        !          2134: {
        !          2135:   /*
        !          2136:    *   2 B     IPv4 Withdrawn Routes Length (zero)
        !          2137:    *   ---     IPv4 Withdrawn Routes NLRI (unused)
        !          2138:    *   2 B     Total Path Attribute Length
        !          2139:    *   1 B     MP_REACH_NLRI hdr - Attribute Flags
        !          2140:    *   1 B     MP_REACH_NLRI hdr - Attribute Type Code
        !          2141:    *   2 B     MP_REACH_NLRI hdr - Length of Attribute Data
        !          2142:    *   2 B     MP_REACH_NLRI data - Address Family Identifier
        !          2143:    *   1 B     MP_REACH_NLRI data - Subsequent Address Family Identifier
        !          2144:    *   1 B     MP_REACH_NLRI data - Length of Next Hop Network Address
        !          2145:    *   var     MP_REACH_NLRI data - Network Address of Next Hop
        !          2146:    *   1 B     MP_REACH_NLRI data - Reserved (zero)
        !          2147:    *   var     MP_REACH_NLRI data - Network Layer Reachability Information
        !          2148:    *   var     Rest of Path Attributes
        !          2149:    *   ---     IPv4 Network Layer Reachability Information (unused)
        !          2150:    */
        !          2151: 
        !          2152:   int lh, lr, la;      /* Lengths of next hop, NLRI and attributes */
        !          2153: 
        !          2154:   /* Begin of MP_REACH_NLRI atribute */
        !          2155:   buf[4] = BAF_OPTIONAL | BAF_EXT_LEN;
        !          2156:   buf[5] = BA_MP_REACH_NLRI;
        !          2157:   put_u16(buf+6, 0);           /* Will be fixed later */
        !          2158:   put_af3(buf+8, s->channel->afi);
        !          2159:   byte *pos = buf+11;
        !          2160: 
        !          2161:   /* Encode attributes to temporary buffer */
        !          2162:   byte *abuf = alloca(MAX_ATTRS_LENGTH);
        !          2163:   la = bgp_encode_attrs(s, buck->eattrs, abuf, abuf + MAX_ATTRS_LENGTH);
        !          2164:   if (la < 0)
        !          2165:   {
        !          2166:     /* Attribute list too long */
        !          2167:     bgp_withdraw_bucket(s->channel, buck);
        !          2168:     return NULL;
        !          2169:   }
        !          2170: 
        !          2171:   /* Encode the next hop */
        !          2172:   lh = bgp_encode_next_hop(s, s->mp_next_hop, pos+1);
        !          2173:   *pos = lh;
        !          2174:   pos += 1+lh;
        !          2175: 
        !          2176:   /* Reserved field */
        !          2177:   *pos++ = 0;
        !          2178: 
        !          2179:   /* Encode the NLRI */
        !          2180:   lr = bgp_encode_nlri(s, buck, pos, end - la);
        !          2181:   pos += lr;
        !          2182: 
        !          2183:   /* End of MP_REACH_NLRI atribute, update data length */
        !          2184:   put_u16(buf+6, pos-buf-8);
        !          2185: 
        !          2186:   /* Copy remaining attributes */
        !          2187:   memcpy(pos, abuf, la);
        !          2188:   pos += la;
        !          2189: 
        !          2190:   /* Initial UPDATE fields */
        !          2191:   put_u16(buf+0, 0);
        !          2192:   put_u16(buf+2, pos-buf-4);
        !          2193: 
        !          2194:   return pos;
        !          2195: }
        !          2196: 
        !          2197: #undef MAX_ATTRS_LENGTH
        !          2198: 
        !          2199: static byte *
        !          2200: bgp_create_ip_unreach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
        !          2201: {
        !          2202:   /*
        !          2203:    *   2 B     Withdrawn Routes Length
        !          2204:    *   var     IPv4 Withdrawn Routes NLRI
        !          2205:    *   2 B     Total Path Attribute Length (zero)
        !          2206:    *   ---     Path Attributes (unused)
        !          2207:    *   ---     IPv4 Network Layer Reachability Information (unused)
        !          2208:    */
        !          2209: 
        !          2210:   uint len = bgp_encode_nlri(s, buck, buf+2, end);
        !          2211: 
        !          2212:   put_u16(buf+0, len);
        !          2213:   put_u16(buf+2+len, 0);
        !          2214: 
        !          2215:   return buf+4+len;
        !          2216: }
        !          2217: 
        !          2218: static byte *
        !          2219: bgp_create_mp_unreach(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, byte *end)
        !          2220: {
        !          2221:   /*
        !          2222:    *   2 B     Withdrawn Routes Length (zero)
        !          2223:    *   ---     IPv4 Withdrawn Routes NLRI (unused)
        !          2224:    *   2 B     Total Path Attribute Length
        !          2225:    *   1 B     MP_UNREACH_NLRI hdr - Attribute Flags
        !          2226:    *   1 B     MP_UNREACH_NLRI hdr - Attribute Type Code
        !          2227:    *   2 B     MP_UNREACH_NLRI hdr - Length of Attribute Data
        !          2228:    *   2 B     MP_UNREACH_NLRI data - Address Family Identifier
        !          2229:    *   1 B     MP_UNREACH_NLRI data - Subsequent Address Family Identifier
        !          2230:    *   var     MP_UNREACH_NLRI data - Network Layer Reachability Information
        !          2231:    *   ---     IPv4 Network Layer Reachability Information (unused)
        !          2232:    */
        !          2233: 
        !          2234:   uint len = bgp_encode_nlri(s, buck, buf+11, end);
        !          2235: 
        !          2236:   put_u16(buf+0, 0);
        !          2237:   put_u16(buf+2, 7+len);
        !          2238: 
        !          2239:   /* Begin of MP_UNREACH_NLRI atribute */
        !          2240:   buf[4] = BAF_OPTIONAL | BAF_EXT_LEN;
        !          2241:   buf[5] = BA_MP_UNREACH_NLRI;
        !          2242:   put_u16(buf+6, 3+len);
        !          2243:   put_af3(buf+8, s->channel->afi);
        !          2244: 
        !          2245:   return buf+11+len;
        !          2246: }
        !          2247: 
        !          2248: static byte *
        !          2249: bgp_create_update(struct bgp_channel *c, byte *buf)
        !          2250: {
        !          2251:   struct bgp_proto *p = (void *) c->c.proto;
        !          2252:   struct bgp_bucket *buck;
        !          2253:   byte *end = buf + (bgp_max_packet_length(p->conn) - BGP_HEADER_LENGTH);
        !          2254:   byte *res = NULL;
        !          2255: 
        !          2256: again: ;
        !          2257: 
        !          2258:   /* Initialize write state */
        !          2259:   struct bgp_write_state s = {
        !          2260:     .proto = p,
        !          2261:     .channel = c,
        !          2262:     .pool = bgp_linpool,
        !          2263:     .mp_reach = (c->afi != BGP_AF_IPV4) || c->ext_next_hop,
        !          2264:     .as4_session = p->as4_session,
        !          2265:     .add_path = c->add_path_tx,
        !          2266:     .mpls = c->desc->mpls,
        !          2267:   };
        !          2268: 
        !          2269:   /* Try unreachable bucket */
        !          2270:   if ((buck = c->withdraw_bucket) && !EMPTY_LIST(buck->prefixes))
        !          2271:   {
        !          2272:     res = (c->afi == BGP_AF_IPV4) && !c->ext_next_hop ?
        !          2273:       bgp_create_ip_unreach(&s, buck, buf, end):
        !          2274:       bgp_create_mp_unreach(&s, buck, buf, end);
        !          2275: 
        !          2276:     goto done;
        !          2277:   }
        !          2278: 
        !          2279:   /* Try reachable buckets */
        !          2280:   if (!EMPTY_LIST(c->bucket_queue))
        !          2281:   {
        !          2282:     buck = HEAD(c->bucket_queue);
        !          2283: 
        !          2284:     /* Cleanup empty buckets */
        !          2285:     if (EMPTY_LIST(buck->prefixes))
        !          2286:     {
        !          2287:       bgp_free_bucket(c, buck);
        !          2288:       goto again;
        !          2289:     }
        !          2290: 
        !          2291:     res = !s.mp_reach ?
        !          2292:       bgp_create_ip_reach(&s, buck, buf, end):
        !          2293:       bgp_create_mp_reach(&s, buck, buf, end);
        !          2294: 
        !          2295:     if (EMPTY_LIST(buck->prefixes))
        !          2296:       bgp_free_bucket(c, buck);
        !          2297:     else
        !          2298:       bgp_defer_bucket(c, buck);
        !          2299: 
        !          2300:     if (!res)
        !          2301:       goto again;
        !          2302: 
        !          2303:     goto done;
        !          2304:   }
        !          2305: 
        !          2306:   /* No more prefixes to send */
        !          2307:   return NULL;
        !          2308: 
        !          2309: done:
        !          2310:   BGP_TRACE_RL(&rl_snd_update, D_PACKETS, "Sending UPDATE");
        !          2311:   lp_flush(s.pool);
        !          2312: 
        !          2313:   return res;
        !          2314: }
        !          2315: 
        !          2316: static byte *
        !          2317: bgp_create_ip_end_mark(struct bgp_channel *c UNUSED, byte *buf)
        !          2318: {
        !          2319:   /* Empty update packet */
        !          2320:   put_u32(buf, 0);
        !          2321: 
        !          2322:   return buf+4;
        !          2323: }
        !          2324: 
        !          2325: static byte *
        !          2326: bgp_create_mp_end_mark(struct bgp_channel *c, byte *buf)
        !          2327: {
        !          2328:   put_u16(buf+0, 0);
        !          2329:   put_u16(buf+2, 6);           /* length 4--9 */
        !          2330: 
        !          2331:   /* Empty MP_UNREACH_NLRI atribute */
        !          2332:   buf[4] = BAF_OPTIONAL;
        !          2333:   buf[5] = BA_MP_UNREACH_NLRI;
        !          2334:   buf[6] = 3;                  /* Length 7--9 */
        !          2335:   put_af3(buf+7, c->afi);
        !          2336: 
        !          2337:   return buf+10;
        !          2338: }
        !          2339: 
        !          2340: static byte *
        !          2341: bgp_create_end_mark(struct bgp_channel *c, byte *buf)
        !          2342: {
        !          2343:   struct bgp_proto *p = (void *) c->c.proto;
        !          2344: 
        !          2345:   BGP_TRACE(D_PACKETS, "Sending END-OF-RIB");
        !          2346: 
        !          2347:   return (c->afi == BGP_AF_IPV4) ?
        !          2348:     bgp_create_ip_end_mark(c, buf):
        !          2349:     bgp_create_mp_end_mark(c, buf);
        !          2350: }
        !          2351: 
        !          2352: static inline void
        !          2353: bgp_rx_end_mark(struct bgp_parse_state *s, u32 afi)
        !          2354: {
        !          2355:   struct bgp_proto *p = s->proto;
        !          2356:   struct bgp_channel *c = bgp_get_channel(p, afi);
        !          2357: 
        !          2358:   BGP_TRACE(D_PACKETS, "Got END-OF-RIB");
        !          2359: 
        !          2360:   if (!c)
        !          2361:     DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
        !          2362: 
        !          2363:   if (c->load_state == BFS_LOADING)
        !          2364:     c->load_state = BFS_NONE;
        !          2365: 
        !          2366:   if (p->p.gr_recovery)
        !          2367:     channel_graceful_restart_unlock(&c->c);
        !          2368: 
        !          2369:   if (c->gr_active)
        !          2370:     bgp_graceful_restart_done(c);
        !          2371: }
        !          2372: 
        !          2373: static inline void
        !          2374: bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_list *ea, byte *nh, uint nh_len)
        !          2375: {
        !          2376:   struct bgp_channel *c = bgp_get_channel(s->proto, afi);
        !          2377:   rta *a = NULL;
        !          2378: 
        !          2379:   if (!c)
        !          2380:     DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi));
        !          2381: 
        !          2382:   s->channel = c;
        !          2383:   s->add_path = c->add_path_rx;
        !          2384:   s->mpls = c->desc->mpls;
        !          2385: 
        !          2386:   s->last_id = 0;
        !          2387:   s->last_src = s->proto->p.main_source;
        !          2388: 
        !          2389:   /*
        !          2390:    * IPv4 BGP and MP-BGP may be used together in one update, therefore we do not
        !          2391:    * add BA_NEXT_HOP in bgp_decode_attrs(), but we add it here independently for
        !          2392:    * IPv4 BGP and MP-BGP. We undo the attribute (and possibly others attached by
        !          2393:    * decode_next_hop hooks) by restoring a->eattrs afterwards.
        !          2394:    */
        !          2395: 
        !          2396:   if (ea)
        !          2397:   {
        !          2398:     a = allocz(RTA_MAX_SIZE);
        !          2399: 
        !          2400:     a->source = RTS_BGP;
        !          2401:     a->scope = SCOPE_UNIVERSE;
        !          2402:     a->from = s->proto->remote_ip;
        !          2403:     a->eattrs = ea;
        !          2404: 
        !          2405:     c->desc->decode_next_hop(s, nh, nh_len, a);
        !          2406:     bgp_finish_attrs(s, a);
        !          2407: 
        !          2408:     /* Handle withdraw during next hop decoding */
        !          2409:     if (s->err_withdraw)
        !          2410:       a = NULL;
        !          2411:   }
        !          2412: 
        !          2413:   c->desc->decode_nlri(s, nlri, len, a);
        !          2414: 
        !          2415:   rta_free(s->cached_rta);
        !          2416:   s->cached_rta = NULL;
        !          2417: }
        !          2418: 
        !          2419: static void
        !          2420: bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
        !          2421: {
        !          2422:   struct bgp_proto *p = conn->bgp;
        !          2423:   ea_list *ea = NULL;
        !          2424: 
        !          2425:   BGP_TRACE_RL(&rl_rcv_update, D_PACKETS, "Got UPDATE");
        !          2426: 
        !          2427:   /* Workaround for some BGP implementations that skip initial KEEPALIVE */
        !          2428:   if (conn->state == BS_OPENCONFIRM)
        !          2429:     bgp_conn_enter_established_state(conn);
        !          2430: 
        !          2431:   if (conn->state != BS_ESTABLISHED)
        !          2432:   { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
        !          2433: 
        !          2434:   bgp_start_timer(conn->hold_timer, conn->hold_time);
        !          2435: 
        !          2436:   /* Initialize parse state */
        !          2437:   struct bgp_parse_state s = {
        !          2438:     .proto = p,
        !          2439:     .pool = bgp_linpool,
        !          2440:     .as4_session = p->as4_session,
        !          2441:   };
        !          2442: 
        !          2443:   /* Parse error handler */
        !          2444:   if (setjmp(s.err_jmpbuf))
        !          2445:   {
        !          2446:     bgp_error(conn, 3, s.err_subcode, NULL, 0);
        !          2447:     goto done;
        !          2448:   }
        !          2449: 
        !          2450:   /* Check minimal length */
        !          2451:   if (len < 23)
        !          2452:   { bgp_error(conn, 1, 2, pkt+16, 2); return; }
        !          2453: 
        !          2454:   /* Skip fixed header */
        !          2455:   uint pos = 19;
        !          2456: 
        !          2457:   /*
        !          2458:    *   UPDATE message format
        !          2459:    *
        !          2460:    *   2 B     IPv4 Withdrawn Routes Length
        !          2461:    *   var     IPv4 Withdrawn Routes NLRI
        !          2462:    *   2 B     Total Path Attribute Length
        !          2463:    *   var     Path Attributes
        !          2464:    *   var     IPv4 Reachable Routes NLRI
        !          2465:    */
        !          2466: 
        !          2467:   s.ip_unreach_len = get_u16(pkt + pos);
        !          2468:   s.ip_unreach_nlri = pkt + pos + 2;
        !          2469:   pos += 2 + s.ip_unreach_len;
        !          2470: 
        !          2471:   if (pos + 2 > len)
        !          2472:     bgp_parse_error(&s, 1);
        !          2473: 
        !          2474:   s.attr_len = get_u16(pkt + pos);
        !          2475:   s.attrs = pkt + pos + 2;
        !          2476:   pos += 2 + s.attr_len;
        !          2477: 
        !          2478:   if (pos > len)
        !          2479:     bgp_parse_error(&s, 1);
        !          2480: 
        !          2481:   s.ip_reach_len = len - pos;
        !          2482:   s.ip_reach_nlri = pkt + pos;
        !          2483: 
        !          2484: 
        !          2485:   if (s.attr_len)
        !          2486:     ea = bgp_decode_attrs(&s, s.attrs, s.attr_len);
        !          2487:   else
        !          2488:     ea = NULL;
        !          2489: 
        !          2490:   /* Check for End-of-RIB marker */
        !          2491:   if (!s.attr_len && !s.ip_unreach_len && !s.ip_reach_len)
        !          2492:   { bgp_rx_end_mark(&s, BGP_AF_IPV4); goto done; }
        !          2493: 
        !          2494:   /* Check for MP End-of-RIB marker */
        !          2495:   if ((s.attr_len < 8) && !s.ip_unreach_len && !s.ip_reach_len &&
        !          2496:       !s.mp_reach_len && !s.mp_unreach_len && s.mp_unreach_af)
        !          2497:   { bgp_rx_end_mark(&s, s.mp_unreach_af); goto done; }
        !          2498: 
        !          2499:   if (s.ip_unreach_len)
        !          2500:     bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_unreach_nlri, s.ip_unreach_len, NULL, NULL, 0);
        !          2501: 
        !          2502:   if (s.mp_unreach_len)
        !          2503:     bgp_decode_nlri(&s, s.mp_unreach_af, s.mp_unreach_nlri, s.mp_unreach_len, NULL, NULL, 0);
        !          2504: 
        !          2505:   if (s.ip_reach_len)
        !          2506:     bgp_decode_nlri(&s, BGP_AF_IPV4, s.ip_reach_nlri, s.ip_reach_len,
        !          2507:                    ea, s.ip_next_hop_data, s.ip_next_hop_len);
        !          2508: 
        !          2509:   if (s.mp_reach_len)
        !          2510:     bgp_decode_nlri(&s, s.mp_reach_af, s.mp_reach_nlri, s.mp_reach_len,
        !          2511:                    ea, s.mp_next_hop_data, s.mp_next_hop_len);
        !          2512: 
        !          2513: done:
        !          2514:   rta_free(s.cached_rta);
        !          2515:   lp_flush(s.pool);
        !          2516:   return;
        !          2517: }
        !          2518: 
        !          2519: static uint
        !          2520: bgp_find_update_afi(byte *pos, uint len)
        !          2521: {
        !          2522:   /*
        !          2523:    * This is stripped-down version of bgp_rx_update(), bgp_decode_attrs() and
        !          2524:    * bgp_decode_mp_[un]reach_nlri() used by MRT code in order to find out which
        !          2525:    * AFI/SAFI is associated with incoming UPDATE. Returns 0 for framing errors.
        !          2526:    */
        !          2527:   if (len < 23)
        !          2528:     return 0;
        !          2529: 
        !          2530:   /* Assume there is no withrawn NLRI, read lengths and move to attribute list */
        !          2531:   uint wlen = get_u16(pos + 19);
        !          2532:   uint alen = get_u16(pos + 21);
        !          2533:   ADVANCE(pos, len, 23);
        !          2534: 
        !          2535:   /* Either non-zero withdrawn NLRI, non-zero reachable NLRI, or IPv4 End-of-RIB */
        !          2536:   if ((wlen != 0) || (alen < len) || !alen)
        !          2537:     return BGP_AF_IPV4;
        !          2538: 
        !          2539:   if (alen > len)
        !          2540:     return 0;
        !          2541: 
        !          2542:   /* Process attribute list (alen == len) */
        !          2543:   while (len)
        !          2544:   {
        !          2545:     if (len < 2)
        !          2546:       return 0;
        !          2547: 
        !          2548:     uint flags = pos[0];
        !          2549:     uint code = pos[1];
        !          2550:     ADVANCE(pos, len, 2);
        !          2551: 
        !          2552:     uint ll = !(flags & BAF_EXT_LEN) ? 1 : 2;
        !          2553:     if (len < ll)
        !          2554:       return 0;
        !          2555: 
        !          2556:     /* Read attribute length and move to attribute body */
        !          2557:     alen = (ll == 1) ? get_u8(pos) : get_u16(pos);
        !          2558:     ADVANCE(pos, len, ll);
        !          2559: 
        !          2560:     if (len < alen)
        !          2561:       return 0;
        !          2562: 
        !          2563:     /* Found MP NLRI */
        !          2564:     if ((code == BA_MP_REACH_NLRI) || (code == BA_MP_UNREACH_NLRI))
        !          2565:     {
        !          2566:       if (alen < 3)
        !          2567:        return 0;
        !          2568: 
        !          2569:       return BGP_AF(get_u16(pos), pos[2]);
        !          2570:     }
        !          2571: 
        !          2572:     /* Move to the next attribute */
        !          2573:     ADVANCE(pos, len, alen);
        !          2574:   }
        !          2575: 
        !          2576:   /* No basic or MP NLRI, but there are some attributes -> error */
        !          2577:   return 0;
        !          2578: }
        !          2579: 
        !          2580: 
        !          2581: /*
        !          2582:  *     ROUTE-REFRESH
        !          2583:  */
        !          2584: 
        !          2585: static inline byte *
        !          2586: bgp_create_route_refresh(struct bgp_channel *c, byte *buf)
        !          2587: {
        !          2588:   struct bgp_proto *p = (void *) c->c.proto;
        !          2589: 
        !          2590:   BGP_TRACE(D_PACKETS, "Sending ROUTE-REFRESH");
        !          2591: 
        !          2592:   /* Original route refresh request, RFC 2918 */
        !          2593:   put_af4(buf, c->afi);
        !          2594:   buf[2] = BGP_RR_REQUEST;
        !          2595: 
        !          2596:   return buf+4;
        !          2597: }
        !          2598: 
        !          2599: static inline byte *
        !          2600: bgp_create_begin_refresh(struct bgp_channel *c, byte *buf)
        !          2601: {
        !          2602:   struct bgp_proto *p = (void *) c->c.proto;
        !          2603: 
        !          2604:   BGP_TRACE(D_PACKETS, "Sending BEGIN-OF-RR");
        !          2605: 
        !          2606:   /* Demarcation of beginning of route refresh (BoRR), RFC 7313 */
        !          2607:   put_af4(buf, c->afi);
        !          2608:   buf[2] = BGP_RR_BEGIN;
        !          2609: 
        !          2610:   return buf+4;
        !          2611: }
        !          2612: 
        !          2613: static inline byte *
        !          2614: bgp_create_end_refresh(struct bgp_channel *c, byte *buf)
        !          2615: {
        !          2616:   struct bgp_proto *p = (void *) c->c.proto;
        !          2617: 
        !          2618:   BGP_TRACE(D_PACKETS, "Sending END-OF-RR");
        !          2619: 
        !          2620:   /* Demarcation of ending of route refresh (EoRR), RFC 7313 */
        !          2621:   put_af4(buf, c->afi);
        !          2622:   buf[2] = BGP_RR_END;
        !          2623: 
        !          2624:   return buf+4;
        !          2625: }
        !          2626: 
        !          2627: static void
        !          2628: bgp_rx_route_refresh(struct bgp_conn *conn, byte *pkt, uint len)
        !          2629: {
        !          2630:   struct bgp_proto *p = conn->bgp;
        !          2631: 
        !          2632:   if (conn->state != BS_ESTABLISHED)
        !          2633:   { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
        !          2634: 
        !          2635:   if (!conn->local_caps->route_refresh)
        !          2636:   { bgp_error(conn, 1, 3, pkt+18, 1); return; }
        !          2637: 
        !          2638:   if (len < (BGP_HEADER_LENGTH + 4))
        !          2639:   { bgp_error(conn, 1, 2, pkt+16, 2); return; }
        !          2640: 
        !          2641:   if (len > (BGP_HEADER_LENGTH + 4))
        !          2642:   { bgp_error(conn, 7, 1, pkt, MIN(len, 2048)); return; }
        !          2643: 
        !          2644:   struct bgp_channel *c = bgp_get_channel(p, get_af4(pkt+19));
        !          2645:   if (!c)
        !          2646:   {
        !          2647:     log(L_WARN "%s: Got ROUTE-REFRESH subtype %u for AF %u.%u, ignoring",
        !          2648:        p->p.name, pkt[21], get_u16(pkt+19), pkt[22]);
        !          2649:     return;
        !          2650:   }
        !          2651: 
        !          2652:   /* RFC 7313 redefined reserved field as RR message subtype */
        !          2653:   uint subtype = p->enhanced_refresh ? pkt[21] : BGP_RR_REQUEST;
        !          2654: 
        !          2655:   switch (subtype)
        !          2656:   {
        !          2657:   case BGP_RR_REQUEST:
        !          2658:     BGP_TRACE(D_PACKETS, "Got ROUTE-REFRESH");
        !          2659:     channel_request_feeding(&c->c);
        !          2660:     break;
        !          2661: 
        !          2662:   case BGP_RR_BEGIN:
        !          2663:     BGP_TRACE(D_PACKETS, "Got BEGIN-OF-RR");
        !          2664:     bgp_refresh_begin(c);
        !          2665:     break;
        !          2666: 
        !          2667:   case BGP_RR_END:
        !          2668:     BGP_TRACE(D_PACKETS, "Got END-OF-RR");
        !          2669:     bgp_refresh_end(c);
        !          2670:     break;
        !          2671: 
        !          2672:   default:
        !          2673:     log(L_WARN "%s: Got ROUTE-REFRESH message with unknown subtype %u, ignoring",
        !          2674:        p->p.name, subtype);
        !          2675:     break;
        !          2676:   }
        !          2677: }
        !          2678: 
        !          2679: static inline struct bgp_channel *
        !          2680: bgp_get_channel_to_send(struct bgp_proto *p, struct bgp_conn *conn)
        !          2681: {
        !          2682:   uint i = conn->last_channel;
        !          2683: 
        !          2684:   /* Try the last channel, but at most several times */
        !          2685:   if ((conn->channels_to_send & (1 << i)) &&
        !          2686:       (conn->last_channel_count < 16))
        !          2687:     goto found;
        !          2688: 
        !          2689:   /* Find channel with non-zero channels_to_send */
        !          2690:   do
        !          2691:   {
        !          2692:     i++;
        !          2693:     if (i >= p->channel_count)
        !          2694:       i = 0;
        !          2695:   }
        !          2696:   while (! (conn->channels_to_send & (1 << i)));
        !          2697: 
        !          2698:   /* Use that channel */
        !          2699:   conn->last_channel = i;
        !          2700:   conn->last_channel_count = 0;
        !          2701: 
        !          2702: found:
        !          2703:   conn->last_channel_count++;
        !          2704:   return p->channel_map[i];
        !          2705: }
        !          2706: 
        !          2707: static inline int
        !          2708: bgp_send(struct bgp_conn *conn, uint type, uint len)
        !          2709: {
        !          2710:   sock *sk = conn->sk;
        !          2711:   byte *buf = sk->tbuf;
        !          2712: 
        !          2713:   memset(buf, 0xff, 16);               /* Marker */
        !          2714:   put_u16(buf+16, len);
        !          2715:   buf[18] = type;
        !          2716: 
        !          2717:   return sk_send(sk, len);
        !          2718: }
        !          2719: 
        !          2720: /**
        !          2721:  * bgp_fire_tx - transmit packets
        !          2722:  * @conn: connection
        !          2723:  *
        !          2724:  * Whenever the transmit buffers of the underlying TCP connection
        !          2725:  * are free and we have any packets queued for sending, the socket functions
        !          2726:  * call bgp_fire_tx() which takes care of selecting the highest priority packet
        !          2727:  * queued (Notification > Keepalive > Open > Update), assembling its header
        !          2728:  * and body and sending it to the connection.
        !          2729:  */
        !          2730: static int
        !          2731: bgp_fire_tx(struct bgp_conn *conn)
        !          2732: {
        !          2733:   struct bgp_proto *p = conn->bgp;
        !          2734:   struct bgp_channel *c;
        !          2735:   byte *buf, *pkt, *end;
        !          2736:   uint s;
        !          2737: 
        !          2738:   if (!conn->sk)
        !          2739:     return 0;
        !          2740: 
        !          2741:   buf = conn->sk->tbuf;
        !          2742:   pkt = buf + BGP_HEADER_LENGTH;
        !          2743:   s = conn->packets_to_send;
        !          2744: 
        !          2745:   if (s & (1 << PKT_SCHEDULE_CLOSE))
        !          2746:   {
        !          2747:     /* We can finally close connection and enter idle state */
        !          2748:     bgp_conn_enter_idle_state(conn);
        !          2749:     return 0;
        !          2750:   }
        !          2751:   if (s & (1 << PKT_NOTIFICATION))
        !          2752:   {
        !          2753:     conn->packets_to_send = 1 << PKT_SCHEDULE_CLOSE;
        !          2754:     end = bgp_create_notification(conn, pkt);
        !          2755:     return bgp_send(conn, PKT_NOTIFICATION, end - buf);
        !          2756:   }
        !          2757:   else if (s & (1 << PKT_OPEN))
        !          2758:   {
        !          2759:     conn->packets_to_send &= ~(1 << PKT_OPEN);
        !          2760:     end = bgp_create_open(conn, pkt);
        !          2761:     return bgp_send(conn, PKT_OPEN, end - buf);
        !          2762:   }
        !          2763:   else if (s & (1 << PKT_KEEPALIVE))
        !          2764:   {
        !          2765:     conn->packets_to_send &= ~(1 << PKT_KEEPALIVE);
        !          2766:     BGP_TRACE(D_PACKETS, "Sending KEEPALIVE");
        !          2767:     bgp_start_timer(conn->keepalive_timer, conn->keepalive_time);
        !          2768:     return bgp_send(conn, PKT_KEEPALIVE, BGP_HEADER_LENGTH);
        !          2769:   }
        !          2770:   else while (conn->channels_to_send)
        !          2771:   {
        !          2772:     c = bgp_get_channel_to_send(p, conn);
        !          2773:     s = c->packets_to_send;
        !          2774: 
        !          2775:     if (s & (1 << PKT_ROUTE_REFRESH))
        !          2776:     {
        !          2777:       c->packets_to_send &= ~(1 << PKT_ROUTE_REFRESH);
        !          2778:       end = bgp_create_route_refresh(c, pkt);
        !          2779:       return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
        !          2780:     }
        !          2781:     else if (s & (1 << PKT_BEGIN_REFRESH))
        !          2782:     {
        !          2783:       /* BoRR is a subtype of RR, but uses separate bit in packets_to_send */
        !          2784:       c->packets_to_send &= ~(1 << PKT_BEGIN_REFRESH);
        !          2785:       end = bgp_create_begin_refresh(c, pkt);
        !          2786:       return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
        !          2787:     }
        !          2788:     else if (s & (1 << PKT_UPDATE))
        !          2789:     {
        !          2790:       end = bgp_create_update(c, pkt);
        !          2791:       if (end)
        !          2792:        return bgp_send(conn, PKT_UPDATE, end - buf);
        !          2793: 
        !          2794:       /* No update to send, perhaps we need to send End-of-RIB or EoRR */
        !          2795:       c->packets_to_send = 0;
        !          2796:       conn->channels_to_send &= ~(1 << c->index);
        !          2797: 
        !          2798:       if (c->feed_state == BFS_LOADED)
        !          2799:       {
        !          2800:        c->feed_state = BFS_NONE;
        !          2801:        end = bgp_create_end_mark(c, pkt);
        !          2802:        return bgp_send(conn, PKT_UPDATE, end - buf);
        !          2803:       }
        !          2804: 
        !          2805:       else if (c->feed_state == BFS_REFRESHED)
        !          2806:       {
        !          2807:        c->feed_state = BFS_NONE;
        !          2808:        end = bgp_create_end_refresh(c, pkt);
        !          2809:        return bgp_send(conn, PKT_ROUTE_REFRESH, end - buf);
        !          2810:       }
        !          2811:     }
        !          2812:     else if (s)
        !          2813:       bug("Channel packets_to_send: %x", s);
        !          2814: 
        !          2815:     c->packets_to_send = 0;
        !          2816:     conn->channels_to_send &= ~(1 << c->index);
        !          2817:   }
        !          2818: 
        !          2819:   return 0;
        !          2820: }
        !          2821: 
        !          2822: /**
        !          2823:  * bgp_schedule_packet - schedule a packet for transmission
        !          2824:  * @conn: connection
        !          2825:  * @c: channel
        !          2826:  * @type: packet type
        !          2827:  *
        !          2828:  * Schedule a packet of type @type to be sent as soon as possible.
        !          2829:  */
        !          2830: void
        !          2831: bgp_schedule_packet(struct bgp_conn *conn, struct bgp_channel *c, int type)
        !          2832: {
        !          2833:   ASSERT(conn->sk);
        !          2834: 
        !          2835:   DBG("BGP: Scheduling packet type %d\n", type);
        !          2836: 
        !          2837:   if (c)
        !          2838:   {
        !          2839:     if (! conn->channels_to_send)
        !          2840:     {
        !          2841:       conn->last_channel = c->index;
        !          2842:       conn->last_channel_count = 0;
        !          2843:     }
        !          2844: 
        !          2845:     c->packets_to_send |= 1 << type;
        !          2846:     conn->channels_to_send |= 1 << c->index;
        !          2847:   }
        !          2848:   else
        !          2849:     conn->packets_to_send |= 1 << type;
        !          2850: 
        !          2851:   if ((conn->sk->tpos == conn->sk->tbuf) && !ev_active(conn->tx_ev))
        !          2852:     ev_schedule(conn->tx_ev);
        !          2853: }
        !          2854: void
        !          2855: bgp_kick_tx(void *vconn)
        !          2856: {
        !          2857:   struct bgp_conn *conn = vconn;
        !          2858: 
        !          2859:   DBG("BGP: kicking TX\n");
        !          2860:   uint max = 1024;
        !          2861:   while (--max && (bgp_fire_tx(conn) > 0))
        !          2862:     ;
        !          2863: 
        !          2864:   if (!max && !ev_active(conn->tx_ev))
        !          2865:     ev_schedule(conn->tx_ev);
        !          2866: }
        !          2867: 
        !          2868: void
        !          2869: bgp_tx(sock *sk)
        !          2870: {
        !          2871:   struct bgp_conn *conn = sk->data;
        !          2872: 
        !          2873:   DBG("BGP: TX hook\n");
        !          2874:   uint max = 1024;
        !          2875:   while (--max && (bgp_fire_tx(conn) > 0))
        !          2876:     ;
        !          2877: 
        !          2878:   if (!max && !ev_active(conn->tx_ev))
        !          2879:     ev_schedule(conn->tx_ev);
        !          2880: }
        !          2881: 
        !          2882: 
        !          2883: static struct {
        !          2884:   byte major, minor;
        !          2885:   byte *msg;
        !          2886: } bgp_msg_table[] = {
        !          2887:   { 1, 0, "Invalid message header" },
        !          2888:   { 1, 1, "Connection not synchronized" },
        !          2889:   { 1, 2, "Bad message length" },
        !          2890:   { 1, 3, "Bad message type" },
        !          2891:   { 2, 0, "Invalid OPEN message" },
        !          2892:   { 2, 1, "Unsupported version number" },
        !          2893:   { 2, 2, "Bad peer AS" },
        !          2894:   { 2, 3, "Bad BGP identifier" },
        !          2895:   { 2, 4, "Unsupported optional parameter" },
        !          2896:   { 2, 5, "Authentication failure" },
        !          2897:   { 2, 6, "Unacceptable hold time" },
        !          2898:   { 2, 7, "Required capability missing" }, /* [RFC5492] */
        !          2899:   { 2, 8, "No supported AFI/SAFI" }, /* This error msg is nonstandard */
        !          2900:   { 3, 0, "Invalid UPDATE message" },
        !          2901:   { 3, 1, "Malformed attribute list" },
        !          2902:   { 3, 2, "Unrecognized well-known attribute" },
        !          2903:   { 3, 3, "Missing mandatory attribute" },
        !          2904:   { 3, 4, "Invalid attribute flags" },
        !          2905:   { 3, 5, "Invalid attribute length" },
        !          2906:   { 3, 6, "Invalid ORIGIN attribute" },
        !          2907:   { 3, 7, "AS routing loop" },         /* Deprecated */
        !          2908:   { 3, 8, "Invalid NEXT_HOP attribute" },
        !          2909:   { 3, 9, "Optional attribute error" },
        !          2910:   { 3, 10, "Invalid network field" },
        !          2911:   { 3, 11, "Malformed AS_PATH" },
        !          2912:   { 4, 0, "Hold timer expired" },
        !          2913:   { 5, 0, "Finite state machine error" }, /* Subcodes are according to [RFC6608] */
        !          2914:   { 5, 1, "Unexpected message in OpenSent state" },
        !          2915:   { 5, 2, "Unexpected message in OpenConfirm state" },
        !          2916:   { 5, 3, "Unexpected message in Established state" },
        !          2917:   { 6, 0, "Cease" }, /* Subcodes are according to [RFC4486] */
        !          2918:   { 6, 1, "Maximum number of prefixes reached" },
        !          2919:   { 6, 2, "Administrative shutdown" },
        !          2920:   { 6, 3, "Peer de-configured" },
        !          2921:   { 6, 4, "Administrative reset" },
        !          2922:   { 6, 5, "Connection rejected" },
        !          2923:   { 6, 6, "Other configuration change" },
        !          2924:   { 6, 7, "Connection collision resolution" },
        !          2925:   { 6, 8, "Out of Resources" },
        !          2926:   { 7, 0, "Invalid ROUTE-REFRESH message" }, /* [RFC7313] */
        !          2927:   { 7, 1, "Invalid ROUTE-REFRESH message length" } /* [RFC7313] */
        !          2928: };
        !          2929: 
        !          2930: /**
        !          2931:  * bgp_error_dsc - return BGP error description
        !          2932:  * @code: BGP error code
        !          2933:  * @subcode: BGP error subcode
        !          2934:  *
        !          2935:  * bgp_error_dsc() returns error description for BGP errors
        !          2936:  * which might be static string or given temporary buffer.
        !          2937:  */
        !          2938: const char *
        !          2939: bgp_error_dsc(uint code, uint subcode)
        !          2940: {
        !          2941:   static char buff[32];
        !          2942:   uint i;
        !          2943: 
        !          2944:   for (i=0; i < ARRAY_SIZE(bgp_msg_table); i++)
        !          2945:     if (bgp_msg_table[i].major == code && bgp_msg_table[i].minor == subcode)
        !          2946:       return bgp_msg_table[i].msg;
        !          2947: 
        !          2948:   bsprintf(buff, "Unknown error %u.%u", code, subcode);
        !          2949:   return buff;
        !          2950: }
        !          2951: 
        !          2952: /* RFC 8203 - shutdown communication message */
        !          2953: static int
        !          2954: bgp_handle_message(struct bgp_proto *p, byte *data, uint len, byte **bp)
        !          2955: {
        !          2956:   byte *msg = data + 1;
        !          2957:   uint msg_len = data[0];
        !          2958:   uint i;
        !          2959: 
        !          2960:   /* Handle zero length message */
        !          2961:   if (msg_len == 0)
        !          2962:     return 1;
        !          2963: 
        !          2964:   /* Handle proper message */
        !          2965:   if (msg_len + 1 > len)
        !          2966:     return 0;
        !          2967: 
        !          2968:   /* Some elementary cleanup */
        !          2969:   for (i = 0; i < msg_len; i++)
        !          2970:     if (msg[i] < ' ')
        !          2971:       msg[i] = ' ';
        !          2972: 
        !          2973:   proto_set_message(&p->p, msg, msg_len);
        !          2974:   *bp += bsprintf(*bp, ": \"%s\"", p->p.message);
        !          2975:   return 1;
        !          2976: }
        !          2977: 
        !          2978: void
        !          2979: bgp_log_error(struct bgp_proto *p, u8 class, char *msg, uint code, uint subcode, byte *data, uint len)
        !          2980: {
        !          2981:   byte argbuf[256+16], *t = argbuf;
        !          2982:   uint i;
        !          2983: 
        !          2984:   /* Don't report Cease messages generated by myself */
        !          2985:   if (code == 6 && class == BE_BGP_TX)
        !          2986:     return;
        !          2987: 
        !          2988:   /* Reset shutdown message */
        !          2989:   if ((code == 6) && ((subcode == 2) || (subcode == 4)))
        !          2990:     proto_set_message(&p->p, NULL, 0);
        !          2991: 
        !          2992:   if (len)
        !          2993:     {
        !          2994:       /* Bad peer AS - we would like to print the AS */
        !          2995:       if ((code == 2) && (subcode == 2) && ((len == 2) || (len == 4)))
        !          2996:        {
        !          2997:          t += bsprintf(t, ": %u", (len == 2) ? get_u16(data) : get_u32(data));
        !          2998:          goto done;
        !          2999:        }
        !          3000: 
        !          3001:       /* RFC 8203 - shutdown communication */
        !          3002:       if (((code == 6) && ((subcode == 2) || (subcode == 4))))
        !          3003:        if (bgp_handle_message(p, data, len, &t))
        !          3004:          goto done;
        !          3005: 
        !          3006:       *t++ = ':';
        !          3007:       *t++ = ' ';
        !          3008:       if (len > 16)
        !          3009:        len = 16;
        !          3010:       for (i=0; i<len; i++)
        !          3011:        t += bsprintf(t, "%02x", data[i]);
        !          3012:     }
        !          3013: 
        !          3014: done:
        !          3015:   *t = 0;
        !          3016:   const byte *dsc = bgp_error_dsc(code, subcode);
        !          3017:   log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, dsc, argbuf);
        !          3018: }
        !          3019: 
        !          3020: static void
        !          3021: bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len)
        !          3022: {
        !          3023:   struct bgp_proto *p = conn->bgp;
        !          3024: 
        !          3025:   if (len < 21)
        !          3026:   { bgp_error(conn, 1, 2, pkt+16, 2); return; }
        !          3027: 
        !          3028:   uint code = pkt[19];
        !          3029:   uint subcode = pkt[20];
        !          3030:   int err = (code != 6);
        !          3031: 
        !          3032:   bgp_log_error(p, BE_BGP_RX, "Received", code, subcode, pkt+21, len-21);
        !          3033:   bgp_store_error(p, conn, BE_BGP_RX, (code << 16) | subcode);
        !          3034: 
        !          3035:   bgp_conn_enter_close_state(conn);
        !          3036:   bgp_schedule_packet(conn, NULL, PKT_SCHEDULE_CLOSE);
        !          3037: 
        !          3038:   if (err)
        !          3039:   {
        !          3040:     bgp_update_startup_delay(p);
        !          3041:     bgp_stop(p, 0, NULL, 0);
        !          3042:   }
        !          3043:   else
        !          3044:   {
        !          3045:     uint subcode_bit = 1 << ((subcode <= 8) ? subcode : 0);
        !          3046:     if (p->cf->disable_after_cease & subcode_bit)
        !          3047:     {
        !          3048:       log(L_INFO "%s: Disabled after Cease notification", p->p.name);
        !          3049:       p->startup_delay = 0;
        !          3050:       p->p.disabled = 1;
        !          3051:     }
        !          3052:   }
        !          3053: }
        !          3054: 
        !          3055: static void
        !          3056: bgp_rx_keepalive(struct bgp_conn *conn)
        !          3057: {
        !          3058:   struct bgp_proto *p = conn->bgp;
        !          3059: 
        !          3060:   BGP_TRACE(D_PACKETS, "Got KEEPALIVE");
        !          3061:   bgp_start_timer(conn->hold_timer, conn->hold_time);
        !          3062: 
        !          3063:   if (conn->state == BS_OPENCONFIRM)
        !          3064:   { bgp_conn_enter_established_state(conn); return; }
        !          3065: 
        !          3066:   if (conn->state != BS_ESTABLISHED)
        !          3067:     bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0);
        !          3068: }
        !          3069: 
        !          3070: 
        !          3071: /**
        !          3072:  * bgp_rx_packet - handle a received packet
        !          3073:  * @conn: BGP connection
        !          3074:  * @pkt: start of the packet
        !          3075:  * @len: packet size
        !          3076:  *
        !          3077:  * bgp_rx_packet() takes a newly received packet and calls the corresponding
        !          3078:  * packet handler according to the packet type.
        !          3079:  */
        !          3080: static void
        !          3081: bgp_rx_packet(struct bgp_conn *conn, byte *pkt, uint len)
        !          3082: {
        !          3083:   byte type = pkt[18];
        !          3084: 
        !          3085:   DBG("BGP: Got packet %02x (%d bytes)\n", type, len);
        !          3086: 
        !          3087:   if (conn->bgp->p.mrtdump & MD_MESSAGES)
        !          3088:     bgp_dump_message(conn, pkt, len);
        !          3089: 
        !          3090:   switch (type)
        !          3091:   {
        !          3092:   case PKT_OPEN:               return bgp_rx_open(conn, pkt, len);
        !          3093:   case PKT_UPDATE:             return bgp_rx_update(conn, pkt, len);
        !          3094:   case PKT_NOTIFICATION:       return bgp_rx_notification(conn, pkt, len);
        !          3095:   case PKT_KEEPALIVE:          return bgp_rx_keepalive(conn);
        !          3096:   case PKT_ROUTE_REFRESH:      return bgp_rx_route_refresh(conn, pkt, len);
        !          3097:   default:                     bgp_error(conn, 1, 3, pkt+18, 1);
        !          3098:   }
        !          3099: }
        !          3100: 
        !          3101: /**
        !          3102:  * bgp_rx - handle received data
        !          3103:  * @sk: socket
        !          3104:  * @size: amount of data received
        !          3105:  *
        !          3106:  * bgp_rx() is called by the socket layer whenever new data arrive from
        !          3107:  * the underlying TCP connection. It assembles the data fragments to packets,
        !          3108:  * checks their headers and framing and passes complete packets to
        !          3109:  * bgp_rx_packet().
        !          3110:  */
        !          3111: int
        !          3112: bgp_rx(sock *sk, uint size)
        !          3113: {
        !          3114:   struct bgp_conn *conn = sk->data;
        !          3115:   byte *pkt_start = sk->rbuf;
        !          3116:   byte *end = pkt_start + size;
        !          3117:   uint i, len;
        !          3118: 
        !          3119:   DBG("BGP: RX hook: Got %d bytes\n", size);
        !          3120:   while (end >= pkt_start + BGP_HEADER_LENGTH)
        !          3121:     {
        !          3122:       if ((conn->state == BS_CLOSE) || (conn->sk != sk))
        !          3123:        return 0;
        !          3124:       for(i=0; i<16; i++)
        !          3125:        if (pkt_start[i] != 0xff)
        !          3126:          {
        !          3127:            bgp_error(conn, 1, 1, NULL, 0);
        !          3128:            break;
        !          3129:          }
        !          3130:       len = get_u16(pkt_start+16);
        !          3131:       if ((len < BGP_HEADER_LENGTH) || (len > bgp_max_packet_length(conn)))
        !          3132:        {
        !          3133:          bgp_error(conn, 1, 2, pkt_start+16, 2);
        !          3134:          break;
        !          3135:        }
        !          3136:       if (end < pkt_start + len)
        !          3137:        break;
        !          3138:       bgp_rx_packet(conn, pkt_start, len);
        !          3139:       pkt_start += len;
        !          3140:     }
        !          3141:   if (pkt_start != sk->rbuf)
        !          3142:     {
        !          3143:       memmove(sk->rbuf, pkt_start, end - pkt_start);
        !          3144:       sk->rpos = sk->rbuf + (end - pkt_start);
        !          3145:     }
        !          3146:   return 0;
        !          3147: }

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