Annotation of embedaddon/bird2/proto/bgp/attrs.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *     BIRD -- BGP Attributes
                      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 "conf/conf.h"
                     21: #include "lib/resource.h"
                     22: #include "lib/string.h"
                     23: #include "lib/unaligned.h"
                     24: 
                     25: #include "bgp.h"
                     26: 
                     27: /*
                     28:  *   UPDATE message error handling
                     29:  *
                     30:  * All checks from RFC 4271 6.3 are done as specified with these exceptions:
                     31:  *  - The semantic check of an IP address from NEXT_HOP attribute is missing.
                     32:  *  - Checks of some optional attribute values are missing.
                     33:  *  - Syntactic and semantic checks of NLRIs (done in DECODE_PREFIX())
                     34:  *    are probably inadequate.
                     35:  *
                     36:  * Loop detection based on AS_PATH causes updates to be withdrawn. RFC
                     37:  * 4271 does not explicitly specify the behavior in that case.
                     38:  *
                     39:  * Loop detection related to route reflection (based on ORIGINATOR_ID
                     40:  * and CLUSTER_LIST) causes updates to be withdrawn. RFC 4456 8
                     41:  * specifies that such updates should be ignored, but that is generally
                     42:  * a bad idea.
                     43:  *
                     44:  * BGP attribute table has several hooks:
                     45:  *
                     46:  * export - Hook that validates and normalizes attribute during export phase.
                     47:  * Receives eattr, may modify it (e.g., sort community lists for canonical
                     48:  * representation), UNSET() it (e.g., skip empty lists), or WITHDRAW() it if
                     49:  * necessary. May assume that eattr has value valid w.r.t. its type, but may be
                     50:  * invalid w.r.t. BGP constraints. Optional.
                     51:  *
                     52:  * encode - Hook that converts internal representation to external one during
                     53:  * packet writing. Receives eattr and puts it in the buffer (including attribute
                     54:  * header). Returns number of bytes, or -1 if not enough space. May assume that
                     55:  * eattr has value valid w.r.t. its type and validated by export hook. Mandatory
                     56:  * for all known attributes that exist internally after export phase (i.e., all
                     57:  * except pseudoattributes MP_(UN)REACH_NLRI).
                     58:  *
                     59:  * decode - Hook that converts external representation to internal one during
                     60:  * packet parsing. Receives attribute data in buffer, validates it and adds
                     61:  * attribute to ea_list. If data are invalid, steps DISCARD(), WITHDRAW() or
                     62:  * bgp_parse_error() may be used to escape. Mandatory for all known attributes.
                     63:  *
                     64:  * format - Optional hook that converts eattr to textual representation.
                     65:  */
                     66: 
                     67: 
                     68: struct bgp_attr_desc {
                     69:   const char *name;
                     70:   uint type;
                     71:   uint flags;
                     72:   void (*export)(struct bgp_export_state *s, eattr *a);
                     73:   int  (*encode)(struct bgp_write_state *s, eattr *a, byte *buf, uint size);
                     74:   void (*decode)(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to);
                     75:   void (*format)(eattr *ea, byte *buf, uint size);
                     76: };
                     77: 
                     78: static const struct bgp_attr_desc bgp_attr_table[];
                     79: 
                     80: static inline int bgp_attr_known(uint code);
                     81: 
                     82: eattr *
                     83: bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, uintptr_t val)
                     84: {
                     85:   ASSERT(bgp_attr_known(code));
                     86: 
                     87:   return ea_set_attr(
                     88:       attrs,
                     89:       pool,
                     90:       EA_CODE(PROTOCOL_BGP, code),
                     91:       flags,
                     92:       bgp_attr_table[code].type,
                     93:       val
                     94:   );
                     95: }
                     96: 
                     97: 
                     98: 
                     99: #define REPORT(msg, args...) \
                    100:   ({ log(L_REMOTE "%s: " msg, s->proto->p.name, ## args); })
                    101: 
                    102: #define DISCARD(msg, args...) \
                    103:   ({ REPORT(msg, ## args); return; })
                    104: 
                    105: #define WITHDRAW(msg, args...) \
                    106:   ({ REPORT(msg, ## args); s->err_withdraw = 1; return; })
                    107: 
                    108: #define UNSET(a) \
                    109:   ({ a->type = EAF_TYPE_UNDEF; return; })
                    110: 
                    111: #define NEW_BGP                "Discarding %s attribute received from AS4-aware neighbor"
                    112: #define BAD_EBGP       "Discarding %s attribute received from EBGP neighbor"
                    113: #define BAD_LENGTH     "Malformed %s attribute - invalid length (%u)"
                    114: #define BAD_VALUE      "Malformed %s attribute - invalid value (%u)"
                    115: #define NO_MANDATORY   "Missing mandatory %s attribute"
                    116: 
                    117: 
                    118: static inline int
                    119: bgp_put_attr_hdr3(byte *buf, uint code, uint flags, uint len)
                    120: {
                    121:   *buf++ = flags;
                    122:   *buf++ = code;
                    123:   *buf++ = len;
                    124:   return 3;
                    125: }
                    126: 
                    127: static inline int
                    128: bgp_put_attr_hdr4(byte *buf, uint code, uint flags, uint len)
                    129: {
                    130:   *buf++ = flags | BAF_EXT_LEN;
                    131:   *buf++ = code;
                    132:   put_u16(buf, len);
                    133:   return 4;
                    134: }
                    135: 
                    136: static inline int
                    137: bgp_put_attr_hdr(byte *buf, uint code, uint flags, uint len)
                    138: {
                    139:   if (len < 256)
                    140:     return bgp_put_attr_hdr3(buf, code, flags, len);
                    141:   else
                    142:     return bgp_put_attr_hdr4(buf, code, flags, len);
                    143: }
                    144: 
                    145: static int
                    146: bgp_encode_u8(struct bgp_write_state *s UNUSED, eattr *a, byte *buf, uint size)
                    147: {
                    148:   if (size < (3+1))
                    149:     return -1;
                    150: 
                    151:   bgp_put_attr_hdr3(buf, EA_ID(a->id), a->flags, 1);
                    152:   buf[3] = a->u.data;
                    153: 
                    154:   return 3+1;
                    155: }
                    156: 
                    157: static int
                    158: bgp_encode_u32(struct bgp_write_state *s UNUSED, eattr *a, byte *buf, uint size)
                    159: {
                    160:   if (size < (3+4))
                    161:     return -1;
                    162: 
                    163:   bgp_put_attr_hdr3(buf, EA_ID(a->id), a->flags, 4);
                    164:   put_u32(buf+3, a->u.data);
                    165: 
                    166:   return 3+4;
                    167: }
                    168: 
                    169: static int
                    170: bgp_encode_u32s(struct bgp_write_state *s UNUSED, eattr *a, byte *buf, uint size)
                    171: {
                    172:   uint len = a->u.ptr->length;
                    173: 
                    174:   if (size < (4+len))
                    175:     return -1;
                    176: 
                    177:   uint hdr = bgp_put_attr_hdr(buf, EA_ID(a->id), a->flags, len);
                    178:   put_u32s(buf + hdr, (u32 *) a->u.ptr->data, len / 4);
                    179: 
                    180:   return hdr + len;
                    181: }
                    182: 
                    183: static int
                    184: bgp_put_attr(byte *buf, uint size, uint code, uint flags, const byte *data, uint len)
                    185: {
                    186:   if (size < (4+len))
                    187:     return -1;
                    188: 
                    189:   uint hdr = bgp_put_attr_hdr(buf, code, flags, len);
                    190:   memcpy(buf + hdr, data, len);
                    191: 
                    192:   return hdr + len;
                    193: }
                    194: 
                    195: static int
                    196: bgp_encode_raw(struct bgp_write_state *s UNUSED, eattr *a, byte *buf, uint size)
                    197: {
                    198:   return bgp_put_attr(buf, size, EA_ID(a->id), a->flags, a->u.ptr->data, a->u.ptr->length);
                    199: }
                    200: 
                    201: 
                    202: /*
                    203:  *     AIGP handling
                    204:  */
                    205: 
                    206: static int
                    207: bgp_aigp_valid(byte *data, uint len, char *err, uint elen)
                    208: {
                    209:   byte *pos = data;
                    210:   char *err_dsc = NULL;
                    211:   uint err_val = 0;
                    212: 
                    213: #define BAD(DSC,VAL) ({ err_dsc = DSC; err_val = VAL; goto bad; })
                    214:   while (len)
                    215:   {
                    216:     if (len < 3)
                    217:       BAD("TLV framing error", len);
                    218: 
                    219:     /* Process one TLV */
                    220:     uint ptype = pos[0];
                    221:     uint plen = get_u16(pos + 1);
                    222: 
                    223:     if (len < plen)
                    224:       BAD("TLV framing error", plen);
                    225: 
                    226:     if (plen < 3)
                    227:       BAD("Bad TLV length", plen);
                    228: 
                    229:     if ((ptype == BGP_AIGP_METRIC) && (plen != 11))
                    230:       BAD("Bad AIGP TLV length", plen);
                    231: 
                    232:     ADVANCE(pos, len, plen);
                    233:   }
                    234: #undef BAD
                    235: 
                    236:   return 1;
                    237: 
                    238: bad:
                    239:   if (err)
                    240:     if (bsnprintf(err, elen, "%s (%u) at %d", err_dsc, err_val, (int) (pos - data)) < 0)
                    241:       err[0] = 0;
                    242: 
                    243:   return 0;
                    244: }
                    245: 
                    246: static const byte *
                    247: bgp_aigp_get_tlv(const struct adata *ad, uint type)
                    248: {
                    249:   if (!ad)
                    250:     return NULL;
                    251: 
                    252:   uint len = ad->length;
                    253:   const byte *pos = ad->data;
                    254: 
                    255:   while (len)
                    256:   {
                    257:     uint ptype = pos[0];
                    258:     uint plen = get_u16(pos + 1);
                    259: 
                    260:     if (ptype == type)
                    261:       return pos;
                    262: 
                    263:     ADVANCE(pos, len, plen);
                    264:   }
                    265: 
                    266:   return NULL;
                    267: }
                    268: 
                    269: static const struct adata *
                    270: bgp_aigp_set_tlv(struct linpool *pool, const struct adata *ad, uint type, byte *data, uint dlen)
                    271: {
                    272:   uint len = ad ? ad->length : 0;
                    273:   const byte *pos = ad ? ad->data : NULL;
                    274:   struct adata *res = lp_alloc_adata(pool, len + 3 + dlen);
                    275:   byte *dst = res->data;
                    276:   byte *tlv = NULL;
                    277:   int del = 0;
                    278: 
                    279:   while (len)
                    280:   {
                    281:     uint ptype = pos[0];
                    282:     uint plen = get_u16(pos + 1);
                    283: 
                    284:     /* Find position for new TLV */
                    285:     if ((ptype >= type) && !tlv)
                    286:     {
                    287:       tlv = dst;
                    288:       dst += 3 + dlen;
                    289:     }
                    290: 
                    291:     /* Skip first matching TLV, copy others */
                    292:     if ((ptype == type) && !del)
                    293:       del = 1;
                    294:     else
                    295:     {
                    296:       memcpy(dst, pos, plen);
                    297:       dst += plen;
                    298:     }
                    299: 
                    300:     ADVANCE(pos, len, plen);
                    301:   }
                    302: 
                    303:   if (!tlv)
                    304:   {
                    305:     tlv = dst;
                    306:     dst += 3 + dlen;
                    307:   }
                    308: 
                    309:   /* Store the TLD */
                    310:   put_u8(tlv + 0, type);
                    311:   put_u16(tlv + 1, 3 + dlen);
                    312:   memcpy(tlv + 3, data, dlen);
                    313: 
                    314:   /* Update length */
                    315:   res->length = dst - res->data;
                    316: 
                    317:   return res;
                    318: }
                    319: 
                    320: static u64 UNUSED
                    321: bgp_aigp_get_metric(const struct adata *ad, u64 def)
                    322: {
                    323:   const byte *b = bgp_aigp_get_tlv(ad, BGP_AIGP_METRIC);
                    324:   return b ? get_u64(b + 3) : def;
                    325: }
                    326: 
                    327: static const struct adata *
                    328: bgp_aigp_set_metric(struct linpool *pool, const struct adata *ad, u64 metric)
                    329: {
                    330:   byte data[8];
                    331:   put_u64(data, metric);
                    332:   return bgp_aigp_set_tlv(pool, ad, BGP_AIGP_METRIC, data, 8);
                    333: }
                    334: 
                    335: int
                    336: bgp_total_aigp_metric_(rte *e, u64 *metric, const struct adata **ad)
                    337: {
                    338:   eattr *a = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AIGP));
                    339:   if (!a)
                    340:     return 0;
                    341: 
                    342:   const byte *b = bgp_aigp_get_tlv(a->u.ptr, BGP_AIGP_METRIC);
                    343:   if (!b)
                    344:     return 0;
                    345: 
                    346:   u64 aigp = get_u64(b + 3);
                    347:   u64 step = e->attrs->igp_metric;
                    348: 
                    349:   if (!rte_resolvable(e) || (step >= IGP_METRIC_UNKNOWN))
                    350:     step = BGP_AIGP_MAX;
                    351: 
                    352:   if (!step)
                    353:     step = 1;
                    354: 
                    355:   *ad = a->u.ptr;
                    356:   *metric = aigp + step;
                    357:   if (*metric < aigp)
                    358:     *metric = BGP_AIGP_MAX;
                    359: 
                    360:   return 1;
                    361: }
                    362: 
                    363: static inline int
                    364: bgp_init_aigp_metric(rte *e, u64 *metric, const struct adata **ad)
                    365: {
                    366:   if (e->attrs->source == RTS_BGP)
                    367:     return 0;
                    368: 
                    369:   *metric = rt_get_igp_metric(e);
                    370:   *ad = NULL;
                    371:   return *metric < IGP_METRIC_UNKNOWN;
                    372: }
                    373: 
                    374: 
                    375: /*
                    376:  *     Attribute hooks
                    377:  */
                    378: 
                    379: static void
                    380: bgp_export_origin(struct bgp_export_state *s, eattr *a)
                    381: {
                    382:   if (a->u.data > 2)
                    383:     WITHDRAW(BAD_VALUE, "ORIGIN", a->u.data);
                    384: }
                    385: 
                    386: static void
                    387: bgp_decode_origin(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    388: {
                    389:   if (len != 1)
                    390:     WITHDRAW(BAD_LENGTH, "ORIGIN", len);
                    391: 
                    392:   if (data[0] > 2)
                    393:     WITHDRAW(BAD_VALUE, "ORIGIN", data[0]);
                    394: 
                    395:   bgp_set_attr_u32(to, s->pool, BA_ORIGIN, flags, data[0]);
                    396: }
                    397: 
                    398: static void
                    399: bgp_format_origin(eattr *a, byte *buf, uint size UNUSED)
                    400: {
                    401:   static const char *bgp_origin_names[] = { "IGP", "EGP", "Incomplete" };
                    402: 
                    403:   bsprintf(buf, (a->u.data <= 2) ? bgp_origin_names[a->u.data] : "?");
                    404: }
                    405: 
                    406: 
                    407: static int
                    408: bgp_encode_as_path(struct bgp_write_state *s, eattr *a, byte *buf, uint size)
                    409: {
                    410:   const byte *data = a->u.ptr->data;
                    411:   uint len = a->u.ptr->length;
                    412: 
                    413:   if (!s->as4_session)
                    414:   {
                    415:     /* Prepare 16-bit AS_PATH (from 32-bit one) in a temporary buffer */
                    416:     byte *dst = alloca(len);
                    417:     len = as_path_32to16(dst, data, len);
                    418:     data = dst;
                    419:   }
                    420: 
                    421:   return bgp_put_attr(buf, size, BA_AS_PATH, a->flags, data, len);
                    422: }
                    423: 
                    424: static void
                    425: bgp_decode_as_path(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    426: {
                    427:   struct bgp_proto *p = s->proto;
                    428:   int as_length = s->as4_session ? 4 : 2;
                    429:   int as_confed = p->cf->confederation && p->is_interior;
                    430:   char err[128];
                    431: 
                    432:   if (!as_path_valid(data, len, as_length, as_confed, err, sizeof(err)))
                    433:     WITHDRAW("Malformed AS_PATH attribute - %s", err);
                    434: 
                    435:   /* In some circumstances check for initial AS_CONFED_SEQUENCE; RFC 5065 5.0 */
                    436:   if (p->is_interior && !p->is_internal &&
                    437:       ((len < 2) || (data[0] != AS_PATH_CONFED_SEQUENCE)))
                    438:     WITHDRAW("Malformed AS_PATH attribute - %s", "missing initial AS_CONFED_SEQUENCE");
                    439: 
                    440:   if (!s->as4_session)
                    441:   {
                    442:     /* Prepare 32-bit AS_PATH (from 16-bit one) in a temporary buffer */
                    443:     byte *src = data;
                    444:     data = alloca(2*len);
                    445:     len = as_path_16to32(data, src, len);
                    446:   }
                    447: 
                    448:   bgp_set_attr_data(to, s->pool, BA_AS_PATH, flags, data, len);
                    449: }
                    450: 
                    451: 
                    452: static int
                    453: bgp_encode_next_hop(struct bgp_write_state *s, eattr *a, byte *buf, uint size)
                    454: {
                    455:   /*
                    456:    * The NEXT_HOP attribute is used only in traditional (IPv4) BGP. In MP-BGP,
                    457:    * the next hop is encoded as a part of the MP_REACH_NLRI attribute, so we
                    458:    * store it and encode it later by AFI-specific hooks.
                    459:    */
                    460: 
                    461:   if (!s->mp_reach)
                    462:   {
                    463:     // ASSERT(a->u.ptr->length == sizeof(ip_addr));
                    464: 
                    465:     /* FIXME: skip IPv6 next hops for IPv4 routes during MRT dump */
                    466:     ip_addr *addr = (void *) a->u.ptr->data;
                    467:     if ((a->u.ptr->length != sizeof(ip_addr)) || !ipa_is_ip4(*addr))
                    468:       return 0;
                    469: 
                    470:     if (size < (3+4))
                    471:       return -1;
                    472: 
                    473:     bgp_put_attr_hdr3(buf, BA_NEXT_HOP, a->flags, 4);
                    474:     put_ip4(buf+3, ipa_to_ip4(*addr));
                    475: 
                    476:     return 3+4;
                    477:   }
                    478:   else
                    479:   {
                    480:     s->mp_next_hop = a;
                    481:     return 0;
                    482:   }
                    483: }
                    484: 
                    485: static void
                    486: bgp_decode_next_hop(struct bgp_parse_state *s, uint code UNUSED, uint flags UNUSED, byte *data, uint len, ea_list **to UNUSED)
                    487: {
                    488:   if (len != 4)
                    489:     WITHDRAW(BAD_LENGTH, "NEXT_HOP", len);
                    490: 
                    491:   /* Semantic checks are done later */
                    492:   s->ip_next_hop_len = len;
                    493:   s->ip_next_hop_data = data;
                    494: }
                    495: 
                    496: /* TODO: This function should use AF-specific hook */
                    497: static void
                    498: bgp_format_next_hop(eattr *a, byte *buf, uint size UNUSED)
                    499: {
                    500:   ip_addr *nh = (void *) a->u.ptr->data;
                    501:   uint len = a->u.ptr->length;
                    502: 
                    503:   ASSERT((len == 16) || (len == 32));
                    504: 
                    505:   /* in IPv6, we may have two addresses in NEXT HOP */
                    506:   if ((len == 16) || ipa_zero(nh[1]))
                    507:     bsprintf(buf, "%I", nh[0]);
                    508:   else
                    509:     bsprintf(buf, "%I %I", nh[0], nh[1]);
                    510: }
                    511: 
                    512: 
                    513: static void
                    514: bgp_decode_med(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    515: {
                    516:   if (len != 4)
                    517:     WITHDRAW(BAD_LENGTH, "MULTI_EXIT_DISC", len);
                    518: 
                    519:   u32 val = get_u32(data);
                    520:   bgp_set_attr_u32(to, s->pool, BA_MULTI_EXIT_DISC, flags, val);
                    521: }
                    522: 
                    523: 
                    524: static void
                    525: bgp_export_local_pref(struct bgp_export_state *s, eattr *a)
                    526: {
                    527:   if (!s->proto->is_interior && !s->proto->cf->allow_local_pref)
                    528:     UNSET(a);
                    529: }
                    530: 
                    531: static void
                    532: bgp_decode_local_pref(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    533: {
                    534:   if (!s->proto->is_interior && !s->proto->cf->allow_local_pref)
                    535:     DISCARD(BAD_EBGP, "LOCAL_PREF");
                    536: 
                    537:   if (len != 4)
                    538:     WITHDRAW(BAD_LENGTH, "LOCAL_PREF", len);
                    539: 
                    540:   u32 val = get_u32(data);
                    541:   bgp_set_attr_u32(to, s->pool, BA_LOCAL_PREF, flags, val);
                    542: }
                    543: 
                    544: 
                    545: static void
                    546: bgp_decode_atomic_aggr(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data UNUSED, uint len, ea_list **to)
                    547: {
                    548:   if (len != 0)
                    549:     DISCARD(BAD_LENGTH, "ATOMIC_AGGR", len);
                    550: 
                    551:   bgp_set_attr_data(to, s->pool, BA_ATOMIC_AGGR, flags, NULL, 0);
                    552: }
                    553: 
                    554: static int
                    555: bgp_encode_aggregator(struct bgp_write_state *s, eattr *a, byte *buf, uint size)
                    556: {
                    557:   const byte *data = a->u.ptr->data;
                    558:   uint len = a->u.ptr->length;
                    559: 
                    560:   if (!s->as4_session)
                    561:   {
                    562:     /* Prepare 16-bit AGGREGATOR (from 32-bit one) in a temporary buffer */
                    563:     byte *dst = alloca(6);
                    564:     len = aggregator_32to16(dst, data);
                    565:   }
                    566: 
                    567:   return bgp_put_attr(buf, size, BA_AGGREGATOR, a->flags, data, len);
                    568: }
                    569: 
                    570: static void
                    571: bgp_decode_aggregator(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    572: {
                    573:   if (len != (s->as4_session ? 8 : 6))
                    574:     DISCARD(BAD_LENGTH, "AGGREGATOR", len);
                    575: 
                    576:   if (!s->as4_session)
                    577:   {
                    578:     /* Prepare 32-bit AGGREGATOR (from 16-bit one) in a temporary buffer */
                    579:     byte *src = data;
                    580:     data = alloca(8);
                    581:     len = aggregator_16to32(data, src);
                    582:   }
                    583: 
                    584:   bgp_set_attr_data(to, s->pool, BA_AGGREGATOR, flags, data, len);
                    585: }
                    586: 
                    587: static void
                    588: bgp_format_aggregator(eattr *a, byte *buf, uint size UNUSED)
                    589: {
                    590:   const byte *data = a->u.ptr->data;
                    591: 
                    592:   bsprintf(buf, "%I4 AS%u", get_ip4(data+4), get_u32(data+0));
                    593: }
                    594: 
                    595: 
                    596: static void
                    597: bgp_export_community(struct bgp_export_state *s, eattr *a)
                    598: {
                    599:   if (a->u.ptr->length == 0)
                    600:     UNSET(a);
                    601: 
                    602:   a->u.ptr = int_set_sort(s->pool, a->u.ptr);
                    603: }
                    604: 
                    605: static void
                    606: bgp_decode_community(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    607: {
                    608:   if (!len || (len % 4))
                    609:     WITHDRAW(BAD_LENGTH, "COMMUNITY", len);
                    610: 
                    611:   struct adata *ad = lp_alloc_adata(s->pool, len);
                    612:   get_u32s(data, (u32 *) ad->data, len / 4);
                    613:   bgp_set_attr_ptr(to, s->pool, BA_COMMUNITY, flags, ad);
                    614: }
                    615: 
                    616: 
                    617: static void
                    618: bgp_export_originator_id(struct bgp_export_state *s, eattr *a)
                    619: {
                    620:   if (!s->proto->is_internal)
                    621:     UNSET(a);
                    622: }
                    623: 
                    624: static void
                    625: bgp_decode_originator_id(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    626: {
                    627:   if (!s->proto->is_internal)
                    628:     DISCARD(BAD_EBGP, "ORIGINATOR_ID");
                    629: 
                    630:   if (len != 4)
                    631:     WITHDRAW(BAD_LENGTH, "ORIGINATOR_ID", len);
                    632: 
                    633:   u32 val = get_u32(data);
                    634:   bgp_set_attr_u32(to, s->pool, BA_ORIGINATOR_ID, flags, val);
                    635: }
                    636: 
                    637: 
                    638: static void
                    639: bgp_export_cluster_list(struct bgp_export_state *s UNUSED, eattr *a)
                    640: {
                    641:   if (!s->proto->is_internal)
                    642:     UNSET(a);
                    643: 
                    644:   if (a->u.ptr->length == 0)
                    645:     UNSET(a);
                    646: }
                    647: 
                    648: static void
                    649: bgp_decode_cluster_list(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    650: {
                    651:   if (!s->proto->is_internal)
                    652:     DISCARD(BAD_EBGP, "CLUSTER_LIST");
                    653: 
                    654:   if (!len || (len % 4))
                    655:     WITHDRAW(BAD_LENGTH, "CLUSTER_LIST", len);
                    656: 
                    657:   struct adata *ad = lp_alloc_adata(s->pool, len);
                    658:   get_u32s(data, (u32 *) ad->data, len / 4);
                    659:   bgp_set_attr_ptr(to, s->pool, BA_CLUSTER_LIST, flags, ad);
                    660: }
                    661: 
                    662: static void
                    663: bgp_format_cluster_list(eattr *a, byte *buf, uint size)
                    664: {
                    665:   /* Truncates cluster lists larger than buflen, probably not a problem */
                    666:   int_set_format(a->u.ptr, 0, -1, buf, size);
                    667: }
                    668: 
                    669: 
                    670: static inline u32
                    671: get_af3(byte *buf)
                    672: {
                    673:   return (get_u16(buf) << 16) | buf[2];
                    674: }
                    675: 
                    676: static void
                    677: bgp_decode_mp_reach_nlri(struct bgp_parse_state *s, uint code UNUSED, uint flags UNUSED, byte *data, uint len, ea_list **to UNUSED)
                    678: {
                    679:   /*
                    680:    *   2 B     MP_REACH_NLRI data - Address Family Identifier
                    681:    *   1 B     MP_REACH_NLRI data - Subsequent Address Family Identifier
                    682:    *   1 B     MP_REACH_NLRI data - Length of Next Hop Network Address
                    683:    *   var     MP_REACH_NLRI data - Network Address of Next Hop
                    684:    *   1 B     MP_REACH_NLRI data - Reserved (zero)
                    685:    *   var     MP_REACH_NLRI data - Network Layer Reachability Information
                    686:    */
                    687: 
                    688:   if ((len < 5) || (len < (5 + (uint) data[3])))
                    689:     bgp_parse_error(s, 9);
                    690: 
                    691:   s->mp_reach_af = get_af3(data);
                    692:   s->mp_next_hop_len = data[3];
                    693:   s->mp_next_hop_data = data + 4;
                    694:   s->mp_reach_len = len - 5 - s->mp_next_hop_len;
                    695:   s->mp_reach_nlri = data + 5 + s->mp_next_hop_len;
                    696: }
                    697: 
                    698: 
                    699: static void
                    700: bgp_decode_mp_unreach_nlri(struct bgp_parse_state *s, uint code UNUSED, uint flags UNUSED, byte *data, uint len, ea_list **to UNUSED)
                    701: {
                    702:   /*
                    703:    *   2 B     MP_UNREACH_NLRI data - Address Family Identifier
                    704:    *   1 B     MP_UNREACH_NLRI data - Subsequent Address Family Identifier
                    705:    *   var     MP_UNREACH_NLRI data - Network Layer Reachability Information
                    706:    */
                    707: 
                    708:   if (len < 3)
                    709:     bgp_parse_error(s, 9);
                    710: 
                    711:   s->mp_unreach_af = get_af3(data);
                    712:   s->mp_unreach_len = len - 3;
                    713:   s->mp_unreach_nlri = data + 3;
                    714: }
                    715: 
                    716: 
                    717: static void
                    718: bgp_export_ext_community(struct bgp_export_state *s, eattr *a)
                    719: {
                    720:   struct adata *ad = ec_set_del_nontrans(s->pool, a->u.ptr);
                    721: 
                    722:   if (ad->length == 0)
                    723:     UNSET(a);
                    724: 
                    725:   ec_set_sort_x(ad);
                    726:   a->u.ptr = ad;
                    727: }
                    728: 
                    729: static void
                    730: bgp_decode_ext_community(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    731: {
                    732:   if (!len || (len % 8))
                    733:     WITHDRAW(BAD_LENGTH, "EXT_COMMUNITY", len);
                    734: 
                    735:   struct adata *ad = lp_alloc_adata(s->pool, len);
                    736:   get_u32s(data, (u32 *) ad->data, len / 4);
                    737:   bgp_set_attr_ptr(to, s->pool, BA_EXT_COMMUNITY, flags, ad);
                    738: }
                    739: 
                    740: 
                    741: static void
                    742: bgp_decode_as4_aggregator(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    743: {
                    744:   if (s->as4_session)
                    745:     DISCARD(NEW_BGP, "AS4_AGGREGATOR");
                    746: 
                    747:   if (len != 8)
                    748:     DISCARD(BAD_LENGTH, "AS4_AGGREGATOR", len);
                    749: 
                    750:   bgp_set_attr_data(to, s->pool, BA_AS4_AGGREGATOR, flags, data, len);
                    751: }
                    752: 
                    753: static void
                    754: bgp_decode_as4_path(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    755: {
                    756:   char err[128];
                    757: 
                    758:   if (s->as4_session)
                    759:     DISCARD(NEW_BGP, "AS4_PATH");
                    760: 
                    761:   if (len < 6)
                    762:     DISCARD(BAD_LENGTH, "AS4_PATH", len);
                    763: 
                    764:   if (!as_path_valid(data, len, 4, 1, err, sizeof(err)))
                    765:     DISCARD("Malformed AS4_PATH attribute - %s", err);
                    766: 
                    767:   struct adata *a = lp_alloc_adata(s->pool, len);
                    768:   memcpy(a->data, data, len);
                    769: 
                    770:   /* AS_CONFED* segments are invalid in AS4_PATH; RFC 6793 6 */
                    771:   if (as_path_contains_confed(a))
                    772:   {
                    773:     REPORT("Discarding AS_CONFED* segment from AS4_PATH attribute");
                    774:     a = as_path_strip_confed(s->pool, a);
                    775:   }
                    776: 
                    777:   bgp_set_attr_ptr(to, s->pool, BA_AS4_PATH, flags, a);
                    778: }
                    779: 
                    780: 
                    781: static void
                    782: bgp_export_aigp(struct bgp_export_state *s, eattr *a)
                    783: {
                    784:   if (!s->channel->cf->aigp)
                    785:     UNSET(a);
                    786: }
                    787: 
                    788: static void
                    789: bgp_decode_aigp(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    790: {
                    791:   char err[128];
                    792: 
                    793:   /* Acceptability test postponed to bgp_finish_attrs() */
                    794: 
                    795:   if ((flags ^ bgp_attr_table[BA_AIGP].flags) & (BAF_OPTIONAL | BAF_TRANSITIVE))
                    796:     DISCARD("Malformed AIGP attribute - conflicting flags (%02x)", flags);
                    797: 
                    798:   if (!bgp_aigp_valid(data, len, err, sizeof(err)))
                    799:     DISCARD("Malformed AIGP attribute - %s", err);
                    800: 
                    801:   bgp_set_attr_data(to, s->pool, BA_AIGP, flags, data, len);
                    802: }
                    803: 
                    804: static void
                    805: bgp_format_aigp(eattr *a, byte *buf, uint size UNUSED)
                    806: {
                    807:   const byte *b = bgp_aigp_get_tlv(a->u.ptr, BGP_AIGP_METRIC);
                    808: 
                    809:   if (!b)
                    810:     bsprintf(buf, "?");
                    811:   else
                    812:     bsprintf(buf, "%lu", get_u64(b + 3));
                    813: }
                    814: 
                    815: 
                    816: static void
                    817: bgp_export_large_community(struct bgp_export_state *s, eattr *a)
                    818: {
                    819:   if (a->u.ptr->length == 0)
                    820:     UNSET(a);
                    821: 
                    822:   a->u.ptr = lc_set_sort(s->pool, a->u.ptr);
                    823: }
                    824: 
                    825: static void
                    826: bgp_decode_large_community(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
                    827: {
                    828:   if (!len || (len % 12))
                    829:     WITHDRAW(BAD_LENGTH, "LARGE_COMMUNITY", len);
                    830: 
                    831:   struct adata *ad = lp_alloc_adata(s->pool, len);
                    832:   get_u32s(data, (u32 *) ad->data, len / 4);
                    833:   bgp_set_attr_ptr(to, s->pool, BA_LARGE_COMMUNITY, flags, ad);
                    834: }
                    835: 
                    836: static void
                    837: bgp_export_mpls_label_stack(struct bgp_export_state *s, eattr *a)
                    838: {
                    839:   net_addr *n = s->route->net->n.addr;
                    840:   u32 *labels = (u32 *) a->u.ptr->data;
                    841:   uint lnum = a->u.ptr->length / 4;
                    842: 
                    843:   /* Perhaps we should just ignore it? */
                    844:   if (!s->mpls)
                    845:     WITHDRAW("Unexpected MPLS stack");
                    846: 
                    847:   /* Empty MPLS stack is not allowed */
                    848:   if (!lnum)
                    849:     WITHDRAW("Malformed MPLS stack - empty");
                    850: 
                    851:   /* This is ugly, but we must ensure that labels fit into NLRI field */
                    852:   if ((24*lnum + (net_is_vpn(n) ? 64 : 0) + net_pxlen(n)) > 255)
                    853:     WITHDRAW("Malformed MPLS stack - too many labels (%u)", lnum);
                    854: 
                    855:   for (uint i = 0; i < lnum; i++)
                    856:   {
                    857:     if (labels[i] > 0xfffff)
                    858:       WITHDRAW("Malformed MPLS stack - invalid label (%u)", labels[i]);
                    859: 
                    860:     /* TODO: Check for special-purpose label values? */
                    861:   }
                    862: }
                    863: 
                    864: static int
                    865: bgp_encode_mpls_label_stack(struct bgp_write_state *s, eattr *a, byte *buf UNUSED, uint size UNUSED)
                    866: {
                    867:   /*
                    868:    * MPLS labels are encoded as a part of the NLRI in MP_REACH_NLRI attribute,
                    869:    * so we store MPLS_LABEL_STACK and encode it later by AFI-specific hooks.
                    870:    */
                    871: 
                    872:   s->mpls_labels = a->u.ptr;
                    873:   return 0;
                    874: }
                    875: 
                    876: static void
                    877: bgp_decode_mpls_label_stack(struct bgp_parse_state *s, uint code UNUSED, uint flags UNUSED, byte *data UNUSED, uint len UNUSED, ea_list **to UNUSED)
                    878: {
                    879:   DISCARD("Discarding received attribute #0");
                    880: }
                    881: 
                    882: static void
                    883: bgp_format_mpls_label_stack(eattr *a, byte *buf, uint size)
                    884: {
                    885:   u32 *labels = (u32 *) a->u.ptr->data;
                    886:   uint lnum = a->u.ptr->length / 4;
                    887:   char *pos = buf;
                    888: 
                    889:   for (uint i = 0; i < lnum; i++)
                    890:   {
                    891:     if (size < 20)
                    892:     {
                    893:       bsprintf(pos, "...");
                    894:       return;
                    895:     }
                    896: 
                    897:     uint l = bsprintf(pos, "%d/", labels[i]);
                    898:     ADVANCE(pos, size, l);
                    899:   }
                    900: 
                    901:   /* Clear last slash or terminate empty string */
                    902:   pos[lnum ? -1 : 0] = 0;
                    903: }
                    904: 
                    905: static inline void
                    906: bgp_decode_unknown(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to)
                    907: {
                    908:   /* Cannot use bgp_set_attr_data() as it works on known attributes only */
                    909:   ea_set_attr_data(to, s->pool, EA_CODE(PROTOCOL_BGP, code), flags, EAF_TYPE_OPAQUE, data, len);
                    910: }
                    911: 
                    912: 
                    913: /*
                    914:  *     Attribute table
                    915:  */
                    916: 
                    917: static const struct bgp_attr_desc bgp_attr_table[] = {
                    918:   [BA_ORIGIN] = {
                    919:     .name = "origin",
                    920:     .type = EAF_TYPE_INT,
                    921:     .flags = BAF_TRANSITIVE,
                    922:     .export = bgp_export_origin,
                    923:     .encode = bgp_encode_u8,
                    924:     .decode = bgp_decode_origin,
                    925:     .format = bgp_format_origin,
                    926:   },
                    927:   [BA_AS_PATH] = {
                    928:     .name = "as_path",
                    929:     .type = EAF_TYPE_AS_PATH,
                    930:     .flags = BAF_TRANSITIVE,
                    931:     .encode = bgp_encode_as_path,
                    932:     .decode = bgp_decode_as_path,
                    933:   },
                    934:   [BA_NEXT_HOP] = {
                    935:     .name = "next_hop",
                    936:     .type = EAF_TYPE_IP_ADDRESS,
                    937:     .flags = BAF_TRANSITIVE,
                    938:     .encode = bgp_encode_next_hop,
                    939:     .decode = bgp_decode_next_hop,
                    940:     .format = bgp_format_next_hop,
                    941:   },
                    942:   [BA_MULTI_EXIT_DISC] = {
                    943:     .name = "med",
                    944:     .type = EAF_TYPE_INT,
                    945:     .flags = BAF_OPTIONAL,
                    946:     .encode = bgp_encode_u32,
                    947:     .decode = bgp_decode_med,
                    948:   },
                    949:   [BA_LOCAL_PREF] = {
                    950:     .name = "local_pref",
                    951:     .type = EAF_TYPE_INT,
                    952:     .flags = BAF_TRANSITIVE,
                    953:     .export = bgp_export_local_pref,
                    954:     .encode = bgp_encode_u32,
                    955:     .decode = bgp_decode_local_pref,
                    956:   },
                    957:   [BA_ATOMIC_AGGR] = {
                    958:     .name = "atomic_aggr",
                    959:     .type = EAF_TYPE_OPAQUE,
                    960:     .flags = BAF_TRANSITIVE,
                    961:     .encode = bgp_encode_raw,
                    962:     .decode = bgp_decode_atomic_aggr,
                    963:   },
                    964:   [BA_AGGREGATOR] = {
                    965:     .name = "aggregator",
                    966:     .type = EAF_TYPE_OPAQUE,
                    967:     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
                    968:     .encode = bgp_encode_aggregator,
                    969:     .decode = bgp_decode_aggregator,
                    970:     .format = bgp_format_aggregator,
                    971:   },
                    972:   [BA_COMMUNITY] = {
                    973:     .name = "community",
                    974:     .type = EAF_TYPE_INT_SET,
                    975:     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
                    976:     .export = bgp_export_community,
                    977:     .encode = bgp_encode_u32s,
                    978:     .decode = bgp_decode_community,
                    979:   },
                    980:   [BA_ORIGINATOR_ID] = {
                    981:     .name = "originator_id",
                    982:     .type = EAF_TYPE_ROUTER_ID,
                    983:     .flags = BAF_OPTIONAL,
                    984:     .export = bgp_export_originator_id,
                    985:     .encode = bgp_encode_u32,
                    986:     .decode = bgp_decode_originator_id,
                    987:   },
                    988:   [BA_CLUSTER_LIST] = {
                    989:     .name = "cluster_list",
                    990:     .type = EAF_TYPE_INT_SET,
                    991:     .flags = BAF_OPTIONAL,
                    992:     .export = bgp_export_cluster_list,
                    993:     .encode = bgp_encode_u32s,
                    994:     .decode = bgp_decode_cluster_list,
                    995:     .format = bgp_format_cluster_list,
                    996:   },
                    997:   [BA_MP_REACH_NLRI] = {
                    998:     .name = "mp_reach_nlri",
                    999:     .type = EAF_TYPE_OPAQUE,
                   1000:     .flags = BAF_OPTIONAL,
                   1001:     .decode = bgp_decode_mp_reach_nlri,
                   1002:   },
                   1003:   [BA_MP_UNREACH_NLRI] = {
                   1004:     .name = "mp_unreach_nlri",
                   1005:     .type = EAF_TYPE_OPAQUE,
                   1006:     .flags = BAF_OPTIONAL,
                   1007:     .decode = bgp_decode_mp_unreach_nlri,
                   1008:   },
                   1009:   [BA_EXT_COMMUNITY] = {
                   1010:     .name = "ext_community",
                   1011:     .type = EAF_TYPE_EC_SET,
                   1012:     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
                   1013:     .export = bgp_export_ext_community,
                   1014:     .encode = bgp_encode_u32s,
                   1015:     .decode = bgp_decode_ext_community,
                   1016:   },
                   1017:   [BA_AS4_PATH] = {
                   1018:     .name = "as4_path",
                   1019:     .type = EAF_TYPE_AS_PATH,
                   1020:     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
                   1021:     .encode = bgp_encode_raw,
                   1022:     .decode = bgp_decode_as4_path,
                   1023:   },
                   1024:   [BA_AS4_AGGREGATOR] = {
                   1025:     .name = "as4_aggregator",
                   1026:     .type = EAF_TYPE_OPAQUE,
                   1027:     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
                   1028:     .encode = bgp_encode_raw,
                   1029:     .decode = bgp_decode_as4_aggregator,
                   1030:     .format = bgp_format_aggregator,
                   1031:   },
                   1032:   [BA_AIGP] = {
                   1033:     .name = "aigp",
                   1034:     .type = EAF_TYPE_OPAQUE,
                   1035:     .flags = BAF_OPTIONAL | BAF_DECODE_FLAGS,
                   1036:     .export = bgp_export_aigp,
                   1037:     .encode = bgp_encode_raw,
                   1038:     .decode = bgp_decode_aigp,
                   1039:     .format = bgp_format_aigp,
                   1040:   },
                   1041:   [BA_LARGE_COMMUNITY] = {
                   1042:     .name = "large_community",
                   1043:     .type = EAF_TYPE_LC_SET,
                   1044:     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
                   1045:     .export = bgp_export_large_community,
                   1046:     .encode = bgp_encode_u32s,
                   1047:     .decode = bgp_decode_large_community,
                   1048:   },
                   1049:   [BA_MPLS_LABEL_STACK] = {
                   1050:     .name = "mpls_label_stack",
                   1051:     .type = EAF_TYPE_INT_SET,
                   1052:     .export = bgp_export_mpls_label_stack,
                   1053:     .encode = bgp_encode_mpls_label_stack,
                   1054:     .decode = bgp_decode_mpls_label_stack,
                   1055:     .format = bgp_format_mpls_label_stack,
                   1056:   },
                   1057: };
                   1058: 
                   1059: static inline int
                   1060: bgp_attr_known(uint code)
                   1061: {
                   1062:   return (code < ARRAY_SIZE(bgp_attr_table)) && bgp_attr_table[code].name;
                   1063: }
                   1064: 
                   1065: 
                   1066: /*
                   1067:  *     Attribute export
                   1068:  */
                   1069: 
                   1070: static inline void
                   1071: bgp_export_attr(struct bgp_export_state *s, eattr *a, ea_list *to)
                   1072: {
                   1073:   if (EA_PROTO(a->id) != PROTOCOL_BGP)
                   1074:     return;
                   1075: 
                   1076:   uint code = EA_ID(a->id);
                   1077: 
                   1078:   if (bgp_attr_known(code))
                   1079:   {
                   1080:     const struct bgp_attr_desc *desc = &bgp_attr_table[code];
                   1081: 
                   1082:     /* The flags might have been zero if the attr was added by filters */
                   1083:     a->flags = (a->flags & BAF_PARTIAL) | desc->flags;
                   1084: 
                   1085:     /* Set partial bit if new opt-trans attribute is attached to non-local route */
                   1086:     if ((s->src != NULL) && (a->type & EAF_ORIGINATED) &&
                   1087:        (a->flags & BAF_OPTIONAL) && (a->flags & BAF_TRANSITIVE))
                   1088:       a->flags |= BAF_PARTIAL;
                   1089: 
                   1090:     /* Call specific hook */
                   1091:     CALL(desc->export, s, a);
                   1092: 
                   1093:     /* Attribute might become undefined in hook */
                   1094:     if ((a->type & EAF_TYPE_MASK) == EAF_TYPE_UNDEF)
                   1095:       return;
                   1096:   }
                   1097:   else
                   1098:   {
                   1099:     /* Don't re-export unknown non-transitive attributes */
                   1100:     if (!(a->flags & BAF_TRANSITIVE))
                   1101:       return;
                   1102: 
                   1103:     a->flags |= BAF_PARTIAL;
                   1104:   }
                   1105: 
                   1106:   /* Append updated attribute */
                   1107:   to->attrs[to->count++] = *a;
                   1108: }
                   1109: 
                   1110: /**
                   1111:  * bgp_export_attrs - export BGP attributes
                   1112:  * @s: BGP export state
                   1113:  * @attrs: a list of extended attributes
                   1114:  *
                   1115:  * The bgp_export_attrs() function takes a list of attributes and merges it to
                   1116:  * one newly allocated and sorted segment. Attributes are validated and
                   1117:  * normalized by type-specific export hooks and attribute flags are updated.
                   1118:  * Some attributes may be eliminated (e.g. unknown non-tranitive attributes, or
                   1119:  * empty community sets).
                   1120:  *
                   1121:  * Result: one sorted attribute list segment, or NULL if attributes are unsuitable.
                   1122:  */
                   1123: static inline ea_list *
                   1124: bgp_export_attrs(struct bgp_export_state *s, ea_list *attrs)
                   1125: {
                   1126:   /* Merge the attribute list */
                   1127:   ea_list *new = lp_alloc(s->pool, ea_scan(attrs));
                   1128:   ea_merge(attrs, new);
                   1129:   ea_sort(new);
                   1130: 
                   1131:   uint i, count;
                   1132:   count = new->count;
                   1133:   new->count = 0;
                   1134: 
                   1135:   /* Export each attribute */
                   1136:   for (i = 0; i < count; i++)
                   1137:     bgp_export_attr(s, &new->attrs[i], new);
                   1138: 
                   1139:   if (s->err_withdraw)
                   1140:     return NULL;
                   1141: 
                   1142:   return new;
                   1143: }
                   1144: 
                   1145: 
                   1146: /*
                   1147:  *     Attribute encoding
                   1148:  */
                   1149: 
                   1150: static inline int
                   1151: bgp_encode_attr(struct bgp_write_state *s, eattr *a, byte *buf, uint size)
                   1152: {
                   1153:   ASSERT(EA_PROTO(a->id) == PROTOCOL_BGP);
                   1154: 
                   1155:   uint code = EA_ID(a->id);
                   1156: 
                   1157:   if (bgp_attr_known(code))
                   1158:     return bgp_attr_table[code].encode(s, a, buf, size);
                   1159:   else
                   1160:     return bgp_encode_raw(s, a, buf, size);
                   1161: }
                   1162: 
                   1163: /**
                   1164:  * bgp_encode_attrs - encode BGP attributes
                   1165:  * @s: BGP write state
                   1166:  * @attrs: a list of extended attributes
                   1167:  * @buf: buffer
                   1168:  * @end: buffer end
                   1169:  *
                   1170:  * The bgp_encode_attrs() function takes a list of extended attributes
                   1171:  * and converts it to its BGP representation (a part of an Update message).
                   1172:  * BGP write state may be fake when called from MRT protocol.
                   1173:  *
                   1174:  * Result: Length of the attribute block generated or -1 if not enough space.
                   1175:  */
                   1176: int
                   1177: bgp_encode_attrs(struct bgp_write_state *s, ea_list *attrs, byte *buf, byte *end)
                   1178: {
                   1179:   byte *pos = buf;
                   1180:   int i, len;
                   1181: 
                   1182:   for (i = 0; i < attrs->count; i++)
                   1183:   {
                   1184:     len = bgp_encode_attr(s, &attrs->attrs[i], pos, end - pos);
                   1185: 
                   1186:     if (len < 0)
                   1187:       return -1;
                   1188: 
                   1189:     pos += len;
                   1190:   }
                   1191: 
                   1192:   return pos - buf;
                   1193: }
                   1194: 
                   1195: 
                   1196: /*
                   1197:  *     Attribute decoding
                   1198:  */
                   1199: 
                   1200: static void bgp_process_as4_attrs(ea_list **attrs, struct linpool *pool);
                   1201: 
                   1202: static inline int
                   1203: bgp_as_path_loopy(struct bgp_proto *p, ea_list *attrs, u32 asn)
                   1204: {
                   1205:   eattr *e = bgp_find_attr(attrs, BA_AS_PATH);
                   1206:   int num = p->cf->allow_local_as + 1;
                   1207:   return (e && (num > 0) && as_path_contains(e->u.ptr, asn, num));
                   1208: }
                   1209: 
                   1210: static inline int
                   1211: bgp_originator_id_loopy(struct bgp_proto *p, ea_list *attrs)
                   1212: {
                   1213:   eattr *e = bgp_find_attr(attrs, BA_ORIGINATOR_ID);
                   1214:   return (e && (e->u.data == p->local_id));
                   1215: }
                   1216: 
                   1217: static inline int
                   1218: bgp_cluster_list_loopy(struct bgp_proto *p, ea_list *attrs)
                   1219: {
                   1220:   eattr *e = bgp_find_attr(attrs, BA_CLUSTER_LIST);
                   1221:   return (e && int_set_contains(e->u.ptr, p->rr_cluster_id));
                   1222: }
                   1223: 
                   1224: static inline void
                   1225: bgp_decode_attr(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to)
                   1226: {
                   1227:   /* Handle duplicate attributes; RFC 7606 3 (g) */
                   1228:   if (BIT32_TEST(s->attrs_seen, code))
                   1229:   {
                   1230:     if ((code == BA_MP_REACH_NLRI) || (code == BA_MP_UNREACH_NLRI))
                   1231:       bgp_parse_error(s, 1);
                   1232:     else
                   1233:       DISCARD("Discarding duplicate attribute (code %u)", code);
                   1234:   }
                   1235:   BIT32_SET(s->attrs_seen, code);
                   1236: 
                   1237:   if (bgp_attr_known(code))
                   1238:   {
                   1239:     const struct bgp_attr_desc *desc = &bgp_attr_table[code];
                   1240: 
                   1241:     /* Handle conflicting flags; RFC 7606 3 (c) */
                   1242:     if (((flags ^ desc->flags) & (BAF_OPTIONAL | BAF_TRANSITIVE)) &&
                   1243:        !(desc->flags & BAF_DECODE_FLAGS))
                   1244:       WITHDRAW("Malformed %s attribute - conflicting flags (%02x)", desc->name, flags);
                   1245: 
                   1246:     desc->decode(s, code, flags, data, len, to);
                   1247:   }
                   1248:   else /* Unknown attribute */
                   1249:   {
                   1250:     if (!(flags & BAF_OPTIONAL))
                   1251:       WITHDRAW("Unknown attribute (code %u) - conflicting flags (%02x)", code, flags);
                   1252: 
                   1253:     bgp_decode_unknown(s, code, flags, data, len, to);
                   1254:   }
                   1255: }
                   1256: 
                   1257: /**
                   1258:  * bgp_decode_attrs - check and decode BGP attributes
                   1259:  * @s: BGP parse state
                   1260:  * @data: start of attribute block
                   1261:  * @len: length of attribute block
                   1262:  *
                   1263:  * This function takes a BGP attribute block (a part of an Update message), checks
                   1264:  * its consistency and converts it to a list of BIRD route attributes represented
                   1265:  * by an (uncached) &rta.
                   1266:  */
                   1267: ea_list *
                   1268: bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len)
                   1269: {
                   1270:   struct bgp_proto *p = s->proto;
                   1271:   ea_list *attrs = NULL;
                   1272:   uint code, flags, alen;
                   1273:   byte *pos = data;
                   1274: 
                   1275:   /* Parse the attributes */
                   1276:   while (len)
                   1277:   {
                   1278:     alen = 0;
                   1279: 
                   1280:     /* Read attribute type */
                   1281:     if (len < 2)
                   1282:       goto framing_error;
                   1283:     flags = pos[0];
                   1284:     code = pos[1];
                   1285:     ADVANCE(pos, len, 2);
                   1286: 
                   1287:     /* Read attribute length */
                   1288:     if (flags & BAF_EXT_LEN)
                   1289:     {
                   1290:       if (len < 2)
                   1291:        goto framing_error;
                   1292:       alen = get_u16(pos);
                   1293:       ADVANCE(pos, len, 2);
                   1294:     }
                   1295:     else
                   1296:     {
                   1297:       if (len < 1)
                   1298:        goto framing_error;
                   1299:       alen = *pos;
                   1300:       ADVANCE(pos, len, 1);
                   1301:     }
                   1302: 
                   1303:     if (alen > len)
                   1304:       goto framing_error;
                   1305: 
                   1306:     DBG("Attr %02x %02x %u\n", code, flags, alen);
                   1307: 
                   1308:     bgp_decode_attr(s, code, flags, pos, alen, &attrs);
                   1309:     ADVANCE(pos, len, alen);
                   1310:   }
                   1311: 
                   1312:   if (s->err_withdraw)
                   1313:     goto withdraw;
                   1314: 
                   1315:   /* If there is no reachability NLRI, we are finished */
                   1316:   if (!s->ip_reach_len && !s->mp_reach_len)
                   1317:     return NULL;
                   1318: 
                   1319: 
                   1320:   /* Handle missing mandatory attributes; RFC 7606 3 (d) */
                   1321:   if (!BIT32_TEST(s->attrs_seen, BA_ORIGIN))
                   1322:   { REPORT(NO_MANDATORY, "ORIGIN"); goto withdraw; }
                   1323: 
                   1324:   if (!BIT32_TEST(s->attrs_seen, BA_AS_PATH))
                   1325:   { REPORT(NO_MANDATORY, "AS_PATH"); goto withdraw; }
                   1326: 
                   1327:   if (s->ip_reach_len && !BIT32_TEST(s->attrs_seen, BA_NEXT_HOP))
                   1328:   { REPORT(NO_MANDATORY, "NEXT_HOP"); goto withdraw; }
                   1329: 
                   1330:   /* When receiving attributes from non-AS4-aware BGP speaker, we have to
                   1331:      reconstruct AS_PATH and AGGREGATOR attributes; RFC 6793 4.2.3 */
                   1332:   if (!p->as4_session)
                   1333:     bgp_process_as4_attrs(&attrs, s->pool);
                   1334: 
                   1335:   /* Reject routes with our ASN in AS_PATH attribute */
                   1336:   if (bgp_as_path_loopy(p, attrs, p->local_as))
                   1337:     goto withdraw;
                   1338: 
                   1339:   /* Reject routes with our Confederation ID in AS_PATH attribute; RFC 5065 4.0 */
                   1340:   if ((p->public_as != p->local_as) && bgp_as_path_loopy(p, attrs, p->public_as))
                   1341:     goto withdraw;
                   1342: 
                   1343:   /* Reject routes with our Router ID in ORIGINATOR_ID attribute; RFC 4456 8 */
                   1344:   if (p->is_internal && bgp_originator_id_loopy(p, attrs))
                   1345:     goto withdraw;
                   1346: 
                   1347:   /* Reject routes with our Cluster ID in CLUSTER_LIST attribute; RFC 4456 8 */
                   1348:   if (p->rr_client && bgp_cluster_list_loopy(p, attrs))
                   1349:     goto withdraw;
                   1350: 
                   1351:   /* If there is no local preference, define one */
                   1352:   if (!BIT32_TEST(s->attrs_seen, BA_LOCAL_PREF))
                   1353:     bgp_set_attr_u32(&attrs, s->pool, BA_LOCAL_PREF, 0, p->cf->default_local_pref);
                   1354: 
                   1355:   return attrs;
                   1356: 
                   1357: 
                   1358: framing_error:
                   1359:   /* RFC 7606 4 - handle attribute framing errors */
                   1360:   REPORT("Malformed attribute list - framing error (%u/%u) at %d",
                   1361:         alen, len, (int) (pos - s->attrs));
                   1362: 
                   1363: withdraw:
                   1364:   /* RFC 7606 5.2 - handle missing NLRI during errors */
                   1365:   if (!s->ip_reach_len && !s->mp_reach_len)
                   1366:     bgp_parse_error(s, 1);
                   1367: 
                   1368:   s->err_withdraw = 1;
                   1369:   return NULL;
                   1370: }
                   1371: 
                   1372: void
                   1373: bgp_finish_attrs(struct bgp_parse_state *s, rta *a)
                   1374: {
                   1375:   /* AIGP test here instead of in bgp_decode_aigp() - we need to know channel */
                   1376:   if (BIT32_TEST(s->attrs_seen, BA_AIGP) && !s->channel->cf->aigp)
                   1377:   {
                   1378:     REPORT("Discarding AIGP attribute received on non-AIGP session");
                   1379:     bgp_unset_attr(&a->eattrs, s->pool, BA_AIGP);
                   1380:   }
                   1381: }
                   1382: 
                   1383: 
                   1384: /*
                   1385:  *     Route bucket hash table
                   1386:  */
                   1387: 
                   1388: #define RBH_KEY(b)             b->eattrs, b->hash
                   1389: #define RBH_NEXT(b)            b->next
                   1390: #define RBH_EQ(a1,h1,a2,h2)    h1 == h2 && ea_same(a1, a2)
                   1391: #define RBH_FN(a,h)            h
                   1392: 
                   1393: #define RBH_REHASH             bgp_rbh_rehash
                   1394: #define RBH_PARAMS             /8, *2, 2, 2, 8, 20
                   1395: 
                   1396: 
                   1397: HASH_DEFINE_REHASH_FN(RBH, struct bgp_bucket)
                   1398: 
                   1399: void
                   1400: bgp_init_bucket_table(struct bgp_channel *c)
                   1401: {
                   1402:   HASH_INIT(c->bucket_hash, c->pool, 8);
                   1403: 
                   1404:   init_list(&c->bucket_queue);
                   1405:   c->withdraw_bucket = NULL;
                   1406: }
                   1407: 
                   1408: void
                   1409: bgp_free_bucket_table(struct bgp_channel *c)
                   1410: {
                   1411:   HASH_FREE(c->bucket_hash);
                   1412: 
                   1413:   struct bgp_bucket *b;
                   1414:   WALK_LIST_FIRST(b, c->bucket_queue)
                   1415:   {
                   1416:     rem_node(&b->send_node);
                   1417:     mb_free(b);
                   1418:   }
                   1419: 
                   1420:   mb_free(c->withdraw_bucket);
                   1421:   c->withdraw_bucket = NULL;
                   1422: }
                   1423: 
                   1424: static struct bgp_bucket *
                   1425: bgp_get_bucket(struct bgp_channel *c, ea_list *new)
                   1426: {
                   1427:   /* Hash and lookup */
                   1428:   u32 hash = ea_hash(new);
                   1429:   struct bgp_bucket *b = HASH_FIND(c->bucket_hash, RBH, new, hash);
                   1430: 
                   1431:   if (b)
                   1432:     return b;
                   1433: 
                   1434:   uint ea_size = sizeof(ea_list) + new->count * sizeof(eattr);
                   1435:   uint ea_size_aligned = BIRD_ALIGN(ea_size, CPU_STRUCT_ALIGN);
                   1436:   uint size = sizeof(struct bgp_bucket) + ea_size_aligned;
                   1437:   uint i;
                   1438:   byte *dest;
                   1439: 
                   1440:   /* Gather total size of non-inline attributes */
                   1441:   for (i = 0; i < new->count; i++)
                   1442:   {
                   1443:     eattr *a = &new->attrs[i];
                   1444: 
                   1445:     if (!(a->type & EAF_EMBEDDED))
                   1446:       size += BIRD_ALIGN(sizeof(struct adata) + a->u.ptr->length, CPU_STRUCT_ALIGN);
                   1447:   }
                   1448: 
                   1449:   /* Create the bucket */
                   1450:   b = mb_alloc(c->pool, size);
                   1451:   init_list(&b->prefixes);
                   1452:   b->hash = hash;
                   1453: 
                   1454:   /* Copy list of extended attributes */
                   1455:   memcpy(b->eattrs, new, ea_size);
                   1456:   dest = ((byte *) b->eattrs) + ea_size_aligned;
                   1457: 
                   1458:   /* Copy values of non-inline attributes */
                   1459:   for (i = 0; i < new->count; i++)
                   1460:   {
                   1461:     eattr *a = &b->eattrs->attrs[i];
                   1462: 
                   1463:     if (!(a->type & EAF_EMBEDDED))
                   1464:     {
                   1465:       const struct adata *oa = a->u.ptr;
                   1466:       struct adata *na = (struct adata *) dest;
                   1467:       memcpy(na, oa, sizeof(struct adata) + oa->length);
                   1468:       a->u.ptr = na;
                   1469:       dest += BIRD_ALIGN(sizeof(struct adata) + na->length, CPU_STRUCT_ALIGN);
                   1470:     }
                   1471:   }
                   1472: 
                   1473:   /* Insert the bucket to send queue and bucket hash */
                   1474:   add_tail(&c->bucket_queue, &b->send_node);
                   1475:   HASH_INSERT2(c->bucket_hash, RBH, c->pool, b);
                   1476: 
                   1477:   return b;
                   1478: }
                   1479: 
                   1480: static struct bgp_bucket *
                   1481: bgp_get_withdraw_bucket(struct bgp_channel *c)
                   1482: {
                   1483:   if (!c->withdraw_bucket)
                   1484:   {
                   1485:     c->withdraw_bucket = mb_allocz(c->pool, sizeof(struct bgp_bucket));
                   1486:     init_list(&c->withdraw_bucket->prefixes);
                   1487:   }
                   1488: 
                   1489:   return c->withdraw_bucket;
                   1490: }
                   1491: 
                   1492: void
                   1493: bgp_free_bucket(struct bgp_channel *c, struct bgp_bucket *b)
                   1494: {
                   1495:   rem_node(&b->send_node);
                   1496:   HASH_REMOVE2(c->bucket_hash, RBH, c->pool, b);
                   1497:   mb_free(b);
                   1498: }
                   1499: 
                   1500: void
                   1501: bgp_defer_bucket(struct bgp_channel *c, struct bgp_bucket *b)
                   1502: {
                   1503:   rem_node(&b->send_node);
                   1504:   add_tail(&c->bucket_queue, &b->send_node);
                   1505: }
                   1506: 
                   1507: void
                   1508: bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b)
                   1509: {
                   1510:   struct bgp_proto *p = (void *) c->c.proto;
                   1511:   struct bgp_bucket *wb = bgp_get_withdraw_bucket(c);
                   1512: 
                   1513:   log(L_ERR "%s: Attribute list too long", p->p.name);
                   1514:   while (!EMPTY_LIST(b->prefixes))
                   1515:   {
                   1516:     struct bgp_prefix *px = HEAD(b->prefixes);
                   1517: 
                   1518:     log(L_ERR "%s: - withdrawing %N", p->p.name, &px->net);
                   1519:     rem_node(&px->buck_node);
                   1520:     add_tail(&wb->prefixes, &px->buck_node);
                   1521:   }
                   1522: }
                   1523: 
                   1524: 
                   1525: /*
                   1526:  *     Prefix hash table
                   1527:  */
                   1528: 
                   1529: #define PXH_KEY(px)            px->net, px->path_id, px->hash
                   1530: #define PXH_NEXT(px)           px->next
                   1531: #define PXH_EQ(n1,i1,h1,n2,i2,h2) h1 == h2 && i1 == i2 && net_equal(n1, n2)
                   1532: #define PXH_FN(n,i,h)          h
                   1533: 
                   1534: #define PXH_REHASH             bgp_pxh_rehash
                   1535: #define PXH_PARAMS             /8, *2, 2, 2, 8, 24
                   1536: 
                   1537: 
                   1538: HASH_DEFINE_REHASH_FN(PXH, struct bgp_prefix)
                   1539: 
                   1540: void
                   1541: bgp_init_prefix_table(struct bgp_channel *c)
                   1542: {
                   1543:   HASH_INIT(c->prefix_hash, c->pool, 8);
                   1544: 
                   1545:   uint alen = net_addr_length[c->c.net_type];
                   1546:   c->prefix_slab = alen ? sl_new(c->pool, sizeof(struct bgp_prefix) + alen) : NULL;
                   1547: }
                   1548: 
                   1549: void
                   1550: bgp_free_prefix_table(struct bgp_channel *c)
                   1551: {
                   1552:   HASH_FREE(c->prefix_hash);
                   1553: 
                   1554:   rfree(c->prefix_slab);
                   1555:   c->prefix_slab = NULL;
                   1556: }
                   1557: 
                   1558: static struct bgp_prefix *
                   1559: bgp_get_prefix(struct bgp_channel *c, net_addr *net, u32 path_id)
                   1560: {
                   1561:   u32 hash = net_hash(net) ^ u32_hash(path_id);
                   1562:   struct bgp_prefix *px = HASH_FIND(c->prefix_hash, PXH, net, path_id, hash);
                   1563: 
                   1564:   if (px)
                   1565:   {
                   1566:     rem_node(&px->buck_node);
                   1567:     return px;
                   1568:   }
                   1569: 
                   1570:   if (c->prefix_slab)
                   1571:     px = sl_alloc(c->prefix_slab);
                   1572:   else
                   1573:     px = mb_alloc(c->pool, sizeof(struct bgp_prefix) + net->length);
                   1574: 
                   1575:   px->buck_node.next = NULL;
                   1576:   px->buck_node.prev = NULL;
                   1577:   px->hash = hash;
                   1578:   px->path_id = path_id;
                   1579:   net_copy(px->net, net);
                   1580: 
                   1581:   HASH_INSERT2(c->prefix_hash, PXH, c->pool, px);
                   1582: 
                   1583:   return px;
                   1584: }
                   1585: 
                   1586: void
                   1587: bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px)
                   1588: {
                   1589:   rem_node(&px->buck_node);
                   1590:   HASH_REMOVE2(c->prefix_hash, PXH, c->pool, px);
                   1591: 
                   1592:   if (c->prefix_slab)
                   1593:     sl_free(c->prefix_slab, px);
                   1594:   else
                   1595:     mb_free(px);
                   1596: }
                   1597: 
                   1598: 
                   1599: /*
                   1600:  *     BGP protocol glue
                   1601:  */
                   1602: 
                   1603: int
                   1604: bgp_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
                   1605: {
                   1606:   rte *e = *new;
                   1607:   struct proto *SRC = e->attrs->src->proto;
                   1608:   struct bgp_proto *p = (struct bgp_proto *) P;
                   1609:   struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (struct bgp_proto *) SRC : NULL;
                   1610: 
                   1611:   /* Reject our routes */
                   1612:   if (src == p)
                   1613:     return -1;
                   1614: 
                   1615:   /* Accept non-BGP routes */
                   1616:   if (src == NULL)
                   1617:     return 0;
                   1618: 
                   1619:   /* IBGP route reflection, RFC 4456 */
                   1620:   if (p->is_internal && src->is_internal && (p->local_as == src->local_as))
                   1621:   {
                   1622:     /* Rejected unless configured as route reflector */
                   1623:     if (!p->rr_client && !src->rr_client)
                   1624:       return -1;
                   1625: 
                   1626:     /* Generally, this should be handled when path is received, but we check it
                   1627:        also here as rr_cluster_id may be undefined or different in src. */
                   1628:     if (p->rr_cluster_id && bgp_cluster_list_loopy(p, e->attrs->eattrs))
                   1629:       return -1;
                   1630:   }
                   1631: 
                   1632:   /* Handle well-known communities, RFC 1997 */
                   1633:   struct eattr *c;
                   1634:   if (p->cf->interpret_communities &&
                   1635:       (c = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY))))
                   1636:   {
                   1637:     const struct adata *d = c->u.ptr;
                   1638: 
                   1639:     /* Do not export anywhere */
                   1640:     if (int_set_contains(d, BGP_COMM_NO_ADVERTISE))
                   1641:       return -1;
                   1642: 
                   1643:     /* Do not export outside of AS (or member-AS) */
                   1644:     if (!p->is_internal && int_set_contains(d, BGP_COMM_NO_EXPORT_SUBCONFED))
                   1645:       return -1;
                   1646: 
                   1647:     /* Do not export outside of AS (or confederation) */
                   1648:     if (!p->is_interior && int_set_contains(d, BGP_COMM_NO_EXPORT))
                   1649:       return -1;
                   1650: 
                   1651:     /* Do not export LLGR_STALE routes to LLGR-ignorant peers */
                   1652:     if (!p->conn->remote_caps->llgr_aware && int_set_contains(d, BGP_COMM_LLGR_STALE))
                   1653:       return -1;
                   1654:   }
                   1655: 
                   1656:   return 0;
                   1657: }
                   1658: 
                   1659: static ea_list *
                   1660: bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *attrs0, struct linpool *pool)
                   1661: {
                   1662:   struct proto *SRC = e->attrs->src->proto;
                   1663:   struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (void *) SRC : NULL;
                   1664:   struct bgp_export_state s = { .proto = p, .channel = c, .pool = pool, .src = src, .route = e, .mpls = c->desc->mpls };
                   1665:   ea_list *attrs = attrs0;
                   1666:   eattr *a;
                   1667:   const adata *ad;
                   1668: 
                   1669:   /* ORIGIN attribute - mandatory, attach if missing */
                   1670:   if (! bgp_find_attr(attrs0, BA_ORIGIN))
                   1671:     bgp_set_attr_u32(&attrs, pool, BA_ORIGIN, 0, src ? ORIGIN_INCOMPLETE : ORIGIN_IGP);
                   1672: 
                   1673:   /* AS_PATH attribute - mandatory */
                   1674:   a = bgp_find_attr(attrs0, BA_AS_PATH);
                   1675:   ad = a ? a->u.ptr : &null_adata;
                   1676: 
                   1677:   /* AS_PATH attribute - strip AS_CONFED* segments outside confederation */
                   1678:   if ((!p->cf->confederation || !p->is_interior) && as_path_contains_confed(ad))
                   1679:     ad = as_path_strip_confed(pool, ad);
                   1680: 
                   1681:   /* AS_PATH attribute - keep or prepend ASN */
                   1682:   if (p->is_internal || p->rs_client)
                   1683:   {
                   1684:     /* IBGP or route server -> just ensure there is one */
                   1685:     if (!a)
                   1686:       bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, &null_adata);
                   1687:   }
                   1688:   else if (p->is_interior)
                   1689:   {
                   1690:     /* Confederation -> prepend ASN as AS_CONFED_SEQUENCE */
                   1691:     ad = as_path_prepend2(pool, ad, AS_PATH_CONFED_SEQUENCE, p->public_as);
                   1692:     bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, ad);
                   1693:   }
                   1694:   else /* Regular EBGP (no RS, no confederation) */
                   1695:   {
                   1696:     /* Regular EBGP -> prepend ASN as regular sequence */
                   1697:     ad = as_path_prepend2(pool, ad, AS_PATH_SEQUENCE, p->public_as);
                   1698:     bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, ad);
                   1699: 
                   1700:     /* MULTI_EXIT_DESC attribute - accept only if set in export filter */
                   1701:     a = bgp_find_attr(attrs0, BA_MULTI_EXIT_DISC);
                   1702:     if (a && !(a->type & EAF_FRESH))
                   1703:       bgp_unset_attr(&attrs, pool, BA_MULTI_EXIT_DISC);
                   1704:   }
                   1705: 
                   1706:   /* NEXT_HOP attribute - delegated to AF-specific hook */
                   1707:   a = bgp_find_attr(attrs0, BA_NEXT_HOP);
                   1708:   bgp_update_next_hop(&s, a, &attrs);
                   1709: 
                   1710:   /* LOCAL_PREF attribute - required for IBGP, attach if missing */
                   1711:   if (p->is_interior && ! bgp_find_attr(attrs0, BA_LOCAL_PREF))
                   1712:     bgp_set_attr_u32(&attrs, pool, BA_LOCAL_PREF, 0, p->cf->default_local_pref);
                   1713: 
                   1714:   /* AIGP attribute - accumulate local metric or originate new one */
                   1715:   u64 metric;
                   1716:   if (s.local_next_hop &&
                   1717:       (bgp_total_aigp_metric_(e, &metric, &ad) ||
                   1718:        (c->cf->aigp_originate && bgp_init_aigp_metric(e, &metric, &ad))))
                   1719:   {
                   1720:     ad = bgp_aigp_set_metric(pool, ad, metric);
                   1721:     bgp_set_attr_ptr(&attrs, pool, BA_AIGP, 0, ad);
                   1722:   }
                   1723: 
                   1724:   /* IBGP route reflection, RFC 4456 */
                   1725:   if (src && src->is_internal && p->is_internal && (src->local_as == p->local_as))
                   1726:   {
                   1727:     /* ORIGINATOR_ID attribute - attach if not already set */
                   1728:     if (! bgp_find_attr(attrs0, BA_ORIGINATOR_ID))
                   1729:       bgp_set_attr_u32(&attrs, pool, BA_ORIGINATOR_ID, 0, src->remote_id);
                   1730: 
                   1731:     /* CLUSTER_LIST attribute - prepend cluster ID */
                   1732:     a = bgp_find_attr(attrs0, BA_CLUSTER_LIST);
                   1733:     ad = a ? a->u.ptr : NULL;
                   1734: 
                   1735:     /* Prepend src cluster ID */
                   1736:     if (src->rr_cluster_id)
                   1737:       ad = int_set_prepend(pool, ad, src->rr_cluster_id);
                   1738: 
                   1739:     /* Prepend dst cluster ID if src and dst clusters are different */
                   1740:     if (p->rr_cluster_id && (src->rr_cluster_id != p->rr_cluster_id))
                   1741:       ad = int_set_prepend(pool, ad, p->rr_cluster_id);
                   1742: 
                   1743:     /* Should be at least one prepended cluster ID */
                   1744:     bgp_set_attr_ptr(&attrs, pool, BA_CLUSTER_LIST, 0, ad);
                   1745:   }
                   1746: 
                   1747:   /* AS4_* transition attributes, RFC 6793 4.2.2 */
                   1748:   if (! p->as4_session)
                   1749:   {
                   1750:     a = bgp_find_attr(attrs, BA_AS_PATH);
                   1751:     if (a && as_path_contains_as4(a->u.ptr))
                   1752:     {
                   1753:       bgp_set_attr_ptr(&attrs, pool, BA_AS_PATH, 0, as_path_to_old(pool, a->u.ptr));
                   1754:       bgp_set_attr_ptr(&attrs, pool, BA_AS4_PATH, 0, as_path_strip_confed(pool, a->u.ptr));
                   1755:     }
                   1756: 
                   1757:     a = bgp_find_attr(attrs, BA_AGGREGATOR);
                   1758:     if (a && aggregator_contains_as4(a->u.ptr))
                   1759:     {
                   1760:       bgp_set_attr_ptr(&attrs, pool, BA_AGGREGATOR, 0, aggregator_to_old(pool, a->u.ptr));
                   1761:       bgp_set_attr_ptr(&attrs, pool, BA_AS4_AGGREGATOR, 0, a->u.ptr);
                   1762:     }
                   1763:   }
                   1764: 
                   1765:   /*
                   1766:    * Presence of mandatory attributes ORIGIN and AS_PATH is ensured by above
                   1767:    * conditions. Presence and validity of quasi-mandatory NEXT_HOP attribute
                   1768:    * should be checked in AF-specific hooks.
                   1769:    */
                   1770: 
                   1771:   /* Apply per-attribute export hooks for validatation and normalization */
                   1772:   return bgp_export_attrs(&s, attrs);
                   1773: }
                   1774: 
                   1775: void
                   1776: bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old)
                   1777: {
                   1778:   struct bgp_proto *p = (void *) P;
                   1779:   struct bgp_channel *c = (void *) C;
                   1780:   struct bgp_bucket *buck;
                   1781:   struct bgp_prefix *px;
                   1782:   u32 path;
                   1783: 
                   1784:   if (new)
                   1785:   {
                   1786:     struct ea_list *attrs = bgp_update_attrs(p, c, new, new->attrs->eattrs, bgp_linpool2);
                   1787: 
                   1788:     /* If attributes are invalid, we fail back to withdraw */
                   1789:     buck = attrs ? bgp_get_bucket(c, attrs) : bgp_get_withdraw_bucket(c);
                   1790:     path = new->attrs->src->global_id;
                   1791: 
                   1792:     lp_flush(bgp_linpool2);
                   1793:   }
                   1794:   else
                   1795:   {
                   1796:     buck = bgp_get_withdraw_bucket(c);
                   1797:     path = old->attrs->src->global_id;
                   1798:   }
                   1799: 
                   1800:   px = bgp_get_prefix(c, n->n.addr, c->add_path_tx ? path : 0);
                   1801:   add_tail(&buck->prefixes, &px->buck_node);
                   1802: 
                   1803:   bgp_schedule_packet(p->conn, c, PKT_UPDATE);
                   1804: }
                   1805: 
                   1806: 
                   1807: static inline u32
                   1808: bgp_get_neighbor(rte *r)
                   1809: {
                   1810:   eattr *e = ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH));
                   1811:   u32 as;
                   1812: 
                   1813:   if (e && as_path_get_first_regular(e->u.ptr, &as))
                   1814:     return as;
                   1815: 
                   1816:   /* If AS_PATH is not defined, we treat rte as locally originated */
                   1817:   struct bgp_proto *p = (void *) r->attrs->src->proto;
                   1818:   return p->cf->confederation ?: p->local_as;
                   1819: }
                   1820: 
                   1821: static inline int
                   1822: rte_stale(rte *r)
                   1823: {
                   1824:   if (r->u.bgp.stale < 0)
                   1825:   {
                   1826:     /* If staleness is unknown, compute and cache it */
                   1827:     eattr *a = ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY));
                   1828:     r->u.bgp.stale = a && int_set_contains(a->u.ptr, BGP_COMM_LLGR_STALE);
                   1829:   }
                   1830: 
                   1831:   return r->u.bgp.stale;
                   1832: }
                   1833: 
                   1834: int
                   1835: bgp_rte_better(rte *new, rte *old)
                   1836: {
                   1837:   struct bgp_proto *new_bgp = (struct bgp_proto *) new->attrs->src->proto;
                   1838:   struct bgp_proto *old_bgp = (struct bgp_proto *) old->attrs->src->proto;
                   1839:   eattr *x, *y;
                   1840:   u32 n, o;
                   1841: 
                   1842:   /* Skip suppressed routes (see bgp_rte_recalculate()) */
                   1843:   n = new->u.bgp.suppressed;
                   1844:   o = old->u.bgp.suppressed;
                   1845:   if (n > o)
                   1846:     return 0;
                   1847:   if (n < o)
                   1848:     return 1;
                   1849: 
                   1850:   /* RFC 4271 9.1.2.1. Route resolvability test */
                   1851:   n = rte_resolvable(new);
                   1852:   o = rte_resolvable(old);
                   1853:   if (n > o)
                   1854:     return 1;
                   1855:   if (n < o)
                   1856:     return 0;
                   1857: 
                   1858:   /* LLGR draft - depreference stale routes */
                   1859:   n = rte_stale(new);
                   1860:   o = rte_stale(old);
                   1861:   if (n > o)
                   1862:     return 0;
                   1863:   if (n < o)
                   1864:     return 1;
                   1865: 
                   1866:  /* Start with local preferences */
                   1867:   x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF));
                   1868:   y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF));
                   1869:   n = x ? x->u.data : new_bgp->cf->default_local_pref;
                   1870:   o = y ? y->u.data : old_bgp->cf->default_local_pref;
                   1871:   if (n > o)
                   1872:     return 1;
                   1873:   if (n < o)
                   1874:     return 0;
                   1875: 
                   1876:   /* RFC 7311 4.1 - Apply AIGP metric */
                   1877:   u64 n2 = bgp_total_aigp_metric(new);
                   1878:   u64 o2 = bgp_total_aigp_metric(old);
                   1879:   if (n2 < o2)
                   1880:     return 1;
                   1881:   if (n2 > o2)
                   1882:     return 0;
                   1883: 
                   1884:   /* RFC 4271 9.1.2.2. a)  Use AS path lengths */
                   1885:   if (new_bgp->cf->compare_path_lengths || old_bgp->cf->compare_path_lengths)
                   1886:   {
                   1887:     x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH));
                   1888:     y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH));
                   1889:     n = x ? as_path_getlen(x->u.ptr) : AS_PATH_MAXLEN;
                   1890:     o = y ? as_path_getlen(y->u.ptr) : AS_PATH_MAXLEN;
                   1891:     if (n < o)
                   1892:       return 1;
                   1893:     if (n > o)
                   1894:       return 0;
                   1895:   }
                   1896: 
                   1897:   /* RFC 4271 9.1.2.2. b) Use origins */
                   1898:   x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN));
                   1899:   y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN));
                   1900:   n = x ? x->u.data : ORIGIN_INCOMPLETE;
                   1901:   o = y ? y->u.data : ORIGIN_INCOMPLETE;
                   1902:   if (n < o)
                   1903:     return 1;
                   1904:   if (n > o)
                   1905:     return 0;
                   1906: 
                   1907:   /* RFC 4271 9.1.2.2. c) Compare MED's */
                   1908:   /* Proper RFC 4271 path selection cannot be interpreted as finding
                   1909:    * the best path in some ordering. It is implemented partially in
                   1910:    * bgp_rte_recalculate() when deterministic_med option is
                   1911:    * active. Without that option, the behavior is just an
                   1912:    * approximation, which in specific situations may lead to
                   1913:    * persistent routing loops, because it is nondeterministic - it
                   1914:    * depends on the order in which routes appeared. But it is also the
                   1915:    * same behavior as used by default in Cisco routers, so it is
                   1916:    * probably not a big issue.
                   1917:    */
                   1918:   if (new_bgp->cf->med_metric || old_bgp->cf->med_metric ||
                   1919:       (bgp_get_neighbor(new) == bgp_get_neighbor(old)))
                   1920:   {
                   1921:     x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC));
                   1922:     y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC));
                   1923:     n = x ? x->u.data : new_bgp->cf->default_med;
                   1924:     o = y ? y->u.data : old_bgp->cf->default_med;
                   1925:     if (n < o)
                   1926:       return 1;
                   1927:     if (n > o)
                   1928:       return 0;
                   1929:   }
                   1930: 
                   1931:   /* RFC 4271 9.1.2.2. d) Prefer external peers */
                   1932:   if (new_bgp->is_interior > old_bgp->is_interior)
                   1933:     return 0;
                   1934:   if (new_bgp->is_interior < old_bgp->is_interior)
                   1935:     return 1;
                   1936: 
                   1937:   /* RFC 4271 9.1.2.2. e) Compare IGP metrics */
                   1938:   n = new_bgp->cf->igp_metric ? new->attrs->igp_metric : 0;
                   1939:   o = old_bgp->cf->igp_metric ? old->attrs->igp_metric : 0;
                   1940:   if (n < o)
                   1941:     return 1;
                   1942:   if (n > o)
                   1943:     return 0;
                   1944: 
                   1945:   /* RFC 4271 9.1.2.2. f) Compare BGP identifiers */
                   1946:   /* RFC 4456 9. a) Use ORIGINATOR_ID instead of local neighbor ID */
                   1947:   x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGINATOR_ID));
                   1948:   y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGINATOR_ID));
                   1949:   n = x ? x->u.data : new_bgp->remote_id;
                   1950:   o = y ? y->u.data : old_bgp->remote_id;
                   1951: 
                   1952:   /* RFC 5004 - prefer older routes */
                   1953:   /* (if both are external and from different peer) */
                   1954:   if ((new_bgp->cf->prefer_older || old_bgp->cf->prefer_older) &&
                   1955:       !new_bgp->is_internal && n != o)
                   1956:     return 0;
                   1957: 
                   1958:   /* rest of RFC 4271 9.1.2.2. f) */
                   1959:   if (n < o)
                   1960:     return 1;
                   1961:   if (n > o)
                   1962:     return 0;
                   1963: 
                   1964:   /* RFC 4456 9. b) Compare cluster list lengths */
                   1965:   x = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_CLUSTER_LIST));
                   1966:   y = ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_CLUSTER_LIST));
                   1967:   n = x ? int_set_get_size(x->u.ptr) : 0;
                   1968:   o = y ? int_set_get_size(y->u.ptr) : 0;
                   1969:   if (n < o)
                   1970:     return 1;
                   1971:   if (n > o)
                   1972:     return 0;
                   1973: 
                   1974:   /* RFC 4271 9.1.2.2. g) Compare peer IP adresses */
                   1975:   return ipa_compare(new_bgp->remote_ip, old_bgp->remote_ip) < 0;
                   1976: }
                   1977: 
                   1978: 
                   1979: int
                   1980: bgp_rte_mergable(rte *pri, rte *sec)
                   1981: {
                   1982:   struct bgp_proto *pri_bgp = (struct bgp_proto *) pri->attrs->src->proto;
                   1983:   struct bgp_proto *sec_bgp = (struct bgp_proto *) sec->attrs->src->proto;
                   1984:   eattr *x, *y;
                   1985:   u32 p, s;
                   1986: 
                   1987:   /* Skip suppressed routes (see bgp_rte_recalculate()) */
                   1988:   if (pri->u.bgp.suppressed != sec->u.bgp.suppressed)
                   1989:     return 0;
                   1990: 
                   1991:   /* RFC 4271 9.1.2.1. Route resolvability test */
                   1992:   if (rte_resolvable(pri) != rte_resolvable(sec))
                   1993:     return 0;
                   1994: 
                   1995:   /* LLGR draft - depreference stale routes */
                   1996:   if (rte_stale(pri) != rte_stale(sec))
                   1997:     return 0;
                   1998: 
                   1999:   /* Start with local preferences */
                   2000:   x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF));
                   2001:   y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF));
                   2002:   p = x ? x->u.data : pri_bgp->cf->default_local_pref;
                   2003:   s = y ? y->u.data : sec_bgp->cf->default_local_pref;
                   2004:   if (p != s)
                   2005:     return 0;
                   2006: 
                   2007:   /* RFC 4271 9.1.2.2. a)  Use AS path lengths */
                   2008:   if (pri_bgp->cf->compare_path_lengths || sec_bgp->cf->compare_path_lengths)
                   2009:   {
                   2010:     x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH));
                   2011:     y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH));
                   2012:     p = x ? as_path_getlen(x->u.ptr) : AS_PATH_MAXLEN;
                   2013:     s = y ? as_path_getlen(y->u.ptr) : AS_PATH_MAXLEN;
                   2014: 
                   2015:     if (p != s)
                   2016:       return 0;
                   2017: 
                   2018: //    if (DELTA(p, s) > pri_bgp->cf->relax_multipath)
                   2019: //      return 0;
                   2020:   }
                   2021: 
                   2022:   /* RFC 4271 9.1.2.2. b) Use origins */
                   2023:   x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN));
                   2024:   y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN));
                   2025:   p = x ? x->u.data : ORIGIN_INCOMPLETE;
                   2026:   s = y ? y->u.data : ORIGIN_INCOMPLETE;
                   2027:   if (p != s)
                   2028:     return 0;
                   2029: 
                   2030:   /* RFC 4271 9.1.2.2. c) Compare MED's */
                   2031:   if (pri_bgp->cf->med_metric || sec_bgp->cf->med_metric ||
                   2032:       (bgp_get_neighbor(pri) == bgp_get_neighbor(sec)))
                   2033:   {
                   2034:     x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC));
                   2035:     y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC));
                   2036:     p = x ? x->u.data : pri_bgp->cf->default_med;
                   2037:     s = y ? y->u.data : sec_bgp->cf->default_med;
                   2038:     if (p != s)
                   2039:       return 0;
                   2040:   }
                   2041: 
                   2042:   /* RFC 4271 9.1.2.2. d) Prefer external peers */
                   2043:   if (pri_bgp->is_interior != sec_bgp->is_interior)
                   2044:     return 0;
                   2045: 
                   2046:   /* RFC 4271 9.1.2.2. e) Compare IGP metrics */
                   2047:   p = pri_bgp->cf->igp_metric ? pri->attrs->igp_metric : 0;
                   2048:   s = sec_bgp->cf->igp_metric ? sec->attrs->igp_metric : 0;
                   2049:   if (p != s)
                   2050:     return 0;
                   2051: 
                   2052:   /* Remaining criteria are ignored */
                   2053: 
                   2054:   return 1;
                   2055: }
                   2056: 
                   2057: 
                   2058: static inline int
                   2059: same_group(rte *r, u32 lpref, u32 lasn)
                   2060: {
                   2061:   return (r->pref == lpref) && (bgp_get_neighbor(r) == lasn);
                   2062: }
                   2063: 
                   2064: static inline int
                   2065: use_deterministic_med(rte *r)
                   2066: {
                   2067:   struct proto *P = r->attrs->src->proto;
                   2068:   return (P->proto == &proto_bgp) && ((struct bgp_proto *) P)->cf->deterministic_med;
                   2069: }
                   2070: 
                   2071: int
                   2072: bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best)
                   2073: {
                   2074:   rte *r, *s;
                   2075:   rte *key = new ? new : old;
                   2076:   u32 lpref = key->pref;
                   2077:   u32 lasn = bgp_get_neighbor(key);
                   2078:   int old_suppressed = old ? old->u.bgp.suppressed : 0;
                   2079: 
                   2080:   /*
                   2081:    * Proper RFC 4271 path selection is a bit complicated, it cannot be
                   2082:    * implemented just by rte_better(), because it is not a linear
                   2083:    * ordering. But it can be splitted to two levels, where the lower
                   2084:    * level chooses the best routes in each group of routes from the
                   2085:    * same neighboring AS and higher level chooses the best route (with
                   2086:    * a slightly different ordering) between the best-in-group routes.
                   2087:    *
                   2088:    * When deterministic_med is disabled, we just ignore this issue and
                   2089:    * choose the best route by bgp_rte_better() alone. If enabled, the
                   2090:    * lower level of the route selection is done here (for the group
                   2091:    * to which the changed route belongs), all routes in group are
                   2092:    * marked as suppressed, just chosen best-in-group is not.
                   2093:    *
                   2094:    * Global best route selection then implements higher level by
                   2095:    * choosing between non-suppressed routes (as they are always
                   2096:    * preferred over suppressed routes). Routes from BGP protocols
                   2097:    * that do not set deterministic_med are just never suppressed. As
                   2098:    * they do not participate in the lower level selection, it is OK
                   2099:    * that this fn is not called for them.
                   2100:    *
                   2101:    * The idea is simple, the implementation is more problematic,
                   2102:    * mostly because of optimizations in rte_recalculate() that
                   2103:    * avoids full recalculation in most cases.
                   2104:    *
                   2105:    * We can assume that at least one of new, old is non-NULL and both
                   2106:    * are from the same protocol with enabled deterministic_med. We
                   2107:    * group routes by both neighbor AS (lasn) and preference (lpref),
                   2108:    * because bgp_rte_better() does not handle preference itself.
                   2109:    */
                   2110: 
                   2111:   /* If new and old are from different groups, we just process that
                   2112:      as two independent events */
                   2113:   if (new && old && !same_group(old, lpref, lasn))
                   2114:   {
                   2115:     int i1, i2;
                   2116:     i1 = bgp_rte_recalculate(table, net, NULL, old, old_best);
                   2117:     i2 = bgp_rte_recalculate(table, net, new, NULL, old_best);
                   2118:     return i1 || i2;
                   2119:   }
                   2120: 
                   2121:   /*
                   2122:    * We could find the best-in-group and then make some shortcuts like
                   2123:    * in rte_recalculate, but as we would have to walk through all
                   2124:    * net->routes just to find it, it is probably not worth. So we
                   2125:    * just have one simple fast case that use just the old route.
                   2126:    * We also set suppressed flag to avoid using it in bgp_rte_better().
                   2127:    */
                   2128: 
                   2129:   if (new)
                   2130:     new->u.bgp.suppressed = 1;
                   2131: 
                   2132:   if (old)
                   2133:   {
                   2134:     old->u.bgp.suppressed = 1;
                   2135: 
                   2136:     /* The fast case - replace not best with worse (or remove not best) */
                   2137:     if (old_suppressed && !(new && bgp_rte_better(new, old)))
                   2138:       return 0;
                   2139:   }
                   2140: 
                   2141:   /* The default case - find a new best-in-group route */
                   2142:   r = new; /* new may not be in the list */
                   2143:   for (s=net->routes; rte_is_valid(s); s=s->next)
                   2144:     if (use_deterministic_med(s) && same_group(s, lpref, lasn))
                   2145:     {
                   2146:       s->u.bgp.suppressed = 1;
                   2147:       if (!r || bgp_rte_better(s, r))
                   2148:        r = s;
                   2149:     }
                   2150: 
                   2151:   /* Simple case - the last route in group disappears */
                   2152:   if (!r)
                   2153:     return 0;
                   2154: 
                   2155:   /* Found if new is mergable with best-in-group */
                   2156:   if (new && (new != r) && bgp_rte_mergable(r, new))
                   2157:     new->u.bgp.suppressed = 0;
                   2158: 
                   2159:   /* Found all existing routes mergable with best-in-group */
                   2160:   for (s=net->routes; rte_is_valid(s); s=s->next)
                   2161:     if (use_deterministic_med(s) && same_group(s, lpref, lasn))
                   2162:       if ((s != r) && bgp_rte_mergable(r, s))
                   2163:        s->u.bgp.suppressed = 0;
                   2164: 
                   2165:   /* Found best-in-group */
                   2166:   r->u.bgp.suppressed = 0;
                   2167: 
                   2168:   /*
                   2169:    * There are generally two reasons why we have to force
                   2170:    * recalculation (return 1): First, the new route may be wrongfully
                   2171:    * chosen to be the best in the first case check in
                   2172:    * rte_recalculate(), this may happen only if old_best is from the
                   2173:    * same group. Second, another (different than new route)
                   2174:    * best-in-group is chosen and that may be the proper best (although
                   2175:    * rte_recalculate() without ignore that possibility).
                   2176:    *
                   2177:    * There are three possible cases according to whether the old route
                   2178:    * was the best in group (OBG, i.e. !old_suppressed) and whether the
                   2179:    * new route is the best in group (NBG, tested by r == new). These
                   2180:    * cases work even if old or new is NULL.
                   2181:    *
                   2182:    * NBG -> new is a possible candidate for the best route, so we just
                   2183:    *        check for the first reason using same_group().
                   2184:    *
                   2185:    * !NBG && OBG -> Second reason applies, return 1
                   2186:    *
                   2187:    * !NBG && !OBG -> Best in group does not change, old != old_best,
                   2188:    *                 rte_better(new, old_best) is false and therefore
                   2189:    *                 the first reason does not apply, return 0
                   2190:    */
                   2191: 
                   2192:   if (r == new)
                   2193:     return old_best && same_group(old_best, lpref, lasn);
                   2194:   else
                   2195:     return !old_suppressed;
                   2196: }
                   2197: 
                   2198: struct rte *
                   2199: bgp_rte_modify_stale(struct rte *r, struct linpool *pool)
                   2200: {
                   2201:   eattr *a = ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY));
                   2202:   const struct adata *ad = a ? a->u.ptr : NULL;
                   2203:   uint flags = a ? a->flags : BAF_PARTIAL;
                   2204: 
                   2205:   if (ad && int_set_contains(ad, BGP_COMM_NO_LLGR))
                   2206:     return NULL;
                   2207: 
                   2208:   if (ad && int_set_contains(ad, BGP_COMM_LLGR_STALE))
                   2209:     return r;
                   2210: 
                   2211:   r = rte_cow_rta(r, pool);
                   2212:   bgp_set_attr_ptr(&(r->attrs->eattrs), pool, BA_COMMUNITY, flags,
                   2213:                   int_set_add(pool, ad, BGP_COMM_LLGR_STALE));
                   2214:   r->u.bgp.stale = 1;
                   2215: 
                   2216:   return r;
                   2217: }
                   2218: 
                   2219: 
                   2220: /*
                   2221:  * Reconstruct AS_PATH and AGGREGATOR according to RFC 6793 4.2.3
                   2222:  */
                   2223: static void
                   2224: bgp_process_as4_attrs(ea_list **attrs, struct linpool *pool)
                   2225: {
                   2226:   eattr *p2 = bgp_find_attr(*attrs, BA_AS_PATH);
                   2227:   eattr *p4 = bgp_find_attr(*attrs, BA_AS4_PATH);
                   2228:   eattr *a2 = bgp_find_attr(*attrs, BA_AGGREGATOR);
                   2229:   eattr *a4 = bgp_find_attr(*attrs, BA_AS4_AGGREGATOR);
                   2230: 
                   2231:   /* First, unset AS4_* attributes */
                   2232:   if (p4) bgp_unset_attr(attrs, pool, BA_AS4_PATH);
                   2233:   if (a4) bgp_unset_attr(attrs, pool, BA_AS4_AGGREGATOR);
                   2234: 
                   2235:   /* Handle AGGREGATOR attribute */
                   2236:   if (a2 && a4)
                   2237:   {
                   2238:     u32 a2_asn = get_u32(a2->u.ptr->data);
                   2239: 
                   2240:     /* If routes were aggregated by an old router, then AS4_PATH and
                   2241:        AS4_AGGREGATOR are invalid. In that case we give up. */
                   2242:     if (a2_asn != AS_TRANS)
                   2243:       return;
                   2244: 
                   2245:     /* Use AS4_AGGREGATOR instead of AGGREGATOR */
                   2246:     a2->u.ptr = a4->u.ptr;
                   2247:   }
                   2248: 
                   2249:   /* Handle AS_PATH attribute */
                   2250:   if (p2 && p4)
                   2251:   {
                   2252:     /* Both as_path_getlen() and as_path_cut() take AS_CONFED* as zero length */
                   2253:     int p2_len = as_path_getlen(p2->u.ptr);
                   2254:     int p4_len = as_path_getlen(p4->u.ptr);
                   2255: 
                   2256:     /* AS_PATH is too short, give up */
                   2257:     if (p2_len < p4_len)
                   2258:       return;
                   2259: 
                   2260:     /* Merge AS_PATH and AS4_PATH */
                   2261:     struct adata *apc = as_path_cut(pool, p2->u.ptr, p2_len - p4_len);
                   2262:     p2->u.ptr = as_path_merge(pool, apc, p4->u.ptr);
                   2263:   }
                   2264: }
                   2265: 
                   2266: int
                   2267: bgp_get_attr(eattr *a, byte *buf, int buflen)
                   2268: {
                   2269:   uint i = EA_ID(a->id);
                   2270:   const struct bgp_attr_desc *d;
                   2271:   int len;
                   2272: 
                   2273:   if (bgp_attr_known(i))
                   2274:   {
                   2275:     d = &bgp_attr_table[i];
                   2276:     len = bsprintf(buf, "%s", d->name);
                   2277:     buf += len;
                   2278:     if (d->format)
                   2279:     {
                   2280:       *buf++ = ':';
                   2281:       *buf++ = ' ';
                   2282:       d->format(a, buf, buflen - len - 2);
                   2283:       return GA_FULL;
                   2284:     }
                   2285:     return GA_NAME;
                   2286:   }
                   2287: 
                   2288:   bsprintf(buf, "%02x%s", i, (a->flags & BAF_TRANSITIVE) ? " [t]" : "");
                   2289:   return GA_NAME;
                   2290: }
                   2291: 
                   2292: void
                   2293: bgp_get_route_info(rte *e, byte *buf)
                   2294: {
                   2295:   eattr *p = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AS_PATH));
                   2296:   eattr *o = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_ORIGIN));
                   2297:   u32 origas;
                   2298: 
                   2299:   buf += bsprintf(buf, " (%d", e->pref);
                   2300: 
                   2301:   if (e->u.bgp.suppressed)
                   2302:     buf += bsprintf(buf, "-");
                   2303: 
                   2304:   if (rte_stale(e))
                   2305:     buf += bsprintf(buf, "s");
                   2306: 
                   2307:   u64 metric = bgp_total_aigp_metric(e);
                   2308:   if (metric < BGP_AIGP_MAX)
                   2309:   {
                   2310:     buf += bsprintf(buf, "/%lu", metric);
                   2311:   }
                   2312:   else if (e->attrs->igp_metric)
                   2313:   {
                   2314:     if (!rte_resolvable(e))
                   2315:       buf += bsprintf(buf, "/-");
                   2316:     else if (e->attrs->igp_metric >= IGP_METRIC_UNKNOWN)
                   2317:       buf += bsprintf(buf, "/?");
                   2318:     else
                   2319:       buf += bsprintf(buf, "/%d", e->attrs->igp_metric);
                   2320:   }
                   2321:   buf += bsprintf(buf, ") [");
                   2322: 
                   2323:   if (p && as_path_get_last(p->u.ptr, &origas))
                   2324:     buf += bsprintf(buf, "AS%u", origas);
                   2325:   if (o)
                   2326:     buf += bsprintf(buf, "%c", "ie?"[o->u.data]);
                   2327:   strcpy(buf, "]");
                   2328: }

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