1 /* BGP attributes management routines.
 
   2    Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
 
   4 This file is part of GNU Zebra.
 
   6 GNU Zebra is free software; you can redistribute it and/or modify it
 
   7 under the terms of the GNU General Public License as published by the
 
   8 Free Software Foundation; either version 2, or (at your option) any
 
  11 GNU Zebra is distributed in the hope that it will be useful, but
 
  12 WITHOUT ANY WARRANTY; without even the implied warranty of
 
  13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
  14 General Public License for more details.
 
  16 You should have received a copy of the GNU General Public License
 
  17 along with GNU Zebra; see the file COPYING.  If not, write to the Free
 
  18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
  34 #include "bgpd/bgpd.h"
 
  35 #include "bgpd/bgp_attr.h"
 
  36 #include "bgpd/bgp_route.h"
 
  37 #include "bgpd/bgp_aspath.h"
 
  38 #include "bgpd/bgp_community.h"
 
  39 #include "bgpd/bgp_debug.h"
 
  40 #include "bgpd/bgp_packet.h"
 
  41 #include "bgpd/bgp_ecommunity.h"
 
  42 #include "bgpd/bgp_lcommunity.h"
 
  44 #include "bgp_encap_types.h"
 
  46 /* Attribute strings for logging. */
 
  47 static const struct message attr_str [] = 
 
  49   { BGP_ATTR_ORIGIN,           "ORIGIN" }, 
 
  50   { BGP_ATTR_AS_PATH,          "AS_PATH" }, 
 
  51   { BGP_ATTR_NEXT_HOP,         "NEXT_HOP" }, 
 
  52   { BGP_ATTR_MULTI_EXIT_DISC,  "MULTI_EXIT_DISC" }, 
 
  53   { BGP_ATTR_LOCAL_PREF,       "LOCAL_PREF" }, 
 
  54   { BGP_ATTR_ATOMIC_AGGREGATE, "ATOMIC_AGGREGATE" }, 
 
  55   { BGP_ATTR_AGGREGATOR,       "AGGREGATOR" }, 
 
  56   { BGP_ATTR_COMMUNITIES,      "COMMUNITY" }, 
 
  57   { BGP_ATTR_ORIGINATOR_ID,    "ORIGINATOR_ID" },
 
  58   { BGP_ATTR_CLUSTER_LIST,     "CLUSTER_LIST" }, 
 
  59   { BGP_ATTR_DPA,              "DPA" },
 
  60   { BGP_ATTR_ADVERTISER,       "ADVERTISER"} ,
 
  61   { BGP_ATTR_RCID_PATH,        "RCID_PATH" },
 
  62   { BGP_ATTR_MP_REACH_NLRI,    "MP_REACH_NLRI" },
 
  63   { BGP_ATTR_MP_UNREACH_NLRI,  "MP_UNREACH_NLRI" },
 
  64   { BGP_ATTR_EXT_COMMUNITIES,  "EXT_COMMUNITIES" },
 
  65   { BGP_ATTR_AS4_PATH,         "AS4_PATH" }, 
 
  66   { BGP_ATTR_AS4_AGGREGATOR,   "AS4_AGGREGATOR" }, 
 
  67   { BGP_ATTR_AS_PATHLIMIT,     "AS_PATHLIMIT" },
 
  68   { BGP_ATTR_ENCAP,            "ENCAP" },
 
  80   { BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY" }
 
  82 static const int attr_str_max = array_size(attr_str);
 
  84 static const struct message attr_flag_str[] =
 
  86   { BGP_ATTR_FLAG_OPTIONAL, "Optional" },
 
  87   { BGP_ATTR_FLAG_TRANS,    "Transitive" },
 
  88   { BGP_ATTR_FLAG_PARTIAL,  "Partial" },
 
  89   /* bgp_attr_flags_diagnose() relies on this bit being last in this list */
 
  90   { BGP_ATTR_FLAG_EXTLEN,   "Extended Length" },
 
  93 static struct hash *cluster_hash;
 
  96 cluster_hash_alloc (void *p)
 
  98   struct cluster_list * val = (struct cluster_list *) p;
 
  99   struct cluster_list *cluster;
 
 101   cluster = XMALLOC (MTYPE_CLUSTER, sizeof (struct cluster_list));
 
 102   cluster->length = val->length;
 
 106       cluster->list = XMALLOC (MTYPE_CLUSTER_VAL, val->length);
 
 107       memcpy (cluster->list, val->list, val->length);
 
 110     cluster->list = NULL;
 
 117 /* Cluster list related functions. */
 
 118 static struct cluster_list *
 
 119 cluster_parse (struct in_addr * pnt, int length)
 
 121   struct cluster_list tmp;
 
 122   struct cluster_list *cluster;
 
 127   cluster = hash_get (cluster_hash, &tmp, cluster_hash_alloc);
 
 133 cluster_loop_check (struct cluster_list *cluster, struct in_addr originator)
 
 137   for (i = 0; i < cluster->length / 4; i++)
 
 138     if (cluster->list[i].s_addr == originator.s_addr)
 
 144 cluster_hash_key_make (void *p)
 
 146   const struct cluster_list *cluster = p;
 
 148   return jhash(cluster->list, cluster->length, 0);
 
 152 cluster_hash_cmp (const void *p1, const void *p2)
 
 154   const struct cluster_list * cluster1 = p1;
 
 155   const struct cluster_list * cluster2 = p2;
 
 157   return (cluster1->length == cluster2->length &&
 
 158           memcmp (cluster1->list, cluster2->list, cluster1->length) == 0);
 
 162 cluster_free (struct cluster_list *cluster)
 
 165     XFREE (MTYPE_CLUSTER_VAL, cluster->list);
 
 166   XFREE (MTYPE_CLUSTER, cluster);
 
 170 static struct cluster_list *
 
 171 cluster_dup (struct cluster_list *cluster)
 
 173   struct cluster_list *new;
 
 175   new = XCALLOC (MTYPE_CLUSTER, sizeof (struct cluster_list));
 
 176   new->length = cluster->length;
 
 180       new->list = XMALLOC (MTYPE_CLUSTER_VAL, cluster->length);
 
 181       memcpy (new->list, cluster->list, cluster->length);
 
 190 static struct cluster_list *
 
 191 cluster_intern (struct cluster_list *cluster)
 
 193   struct cluster_list *find;
 
 195   find = hash_get (cluster_hash, cluster, cluster_hash_alloc);
 
 202 cluster_unintern (struct cluster_list **cluster)
 
 204   struct cluster_list *c = *cluster;
 
 210       hash_release (cluster_hash, c);
 
 219   cluster_hash = hash_create (cluster_hash_key_make, cluster_hash_cmp);
 
 223 cluster_finish (void)
 
 225   hash_clean (cluster_hash, (void (*)(void *))cluster_free);
 
 226   hash_free (cluster_hash);
 
 230 struct bgp_attr_encap_subtlv *
 
 231 encap_tlv_dup(struct bgp_attr_encap_subtlv *orig)
 
 233     struct bgp_attr_encap_subtlv *new;
 
 234     struct bgp_attr_encap_subtlv *tail;
 
 235     struct bgp_attr_encap_subtlv *p;
 
 237     for (p = orig, tail = new = NULL; p; p = p->next) {
 
 238         int size = sizeof(struct bgp_attr_encap_subtlv) - 1 + p->length;
 
 240             tail->next = XCALLOC(MTYPE_ENCAP_TLV, size);
 
 243             tail = new = XCALLOC(MTYPE_ENCAP_TLV, size);
 
 246         memcpy(tail, p, size);
 
 254 encap_free(struct bgp_attr_encap_subtlv *p)
 
 256     struct bgp_attr_encap_subtlv *next;
 
 260         XFREE(MTYPE_ENCAP_TLV, p);
 
 266 bgp_attr_flush_encap(struct attr *attr)
 
 268     if (!attr || !attr->extra)
 
 271     if (attr->extra->encap_subtlvs) {
 
 272         encap_free(attr->extra->encap_subtlvs);
 
 273         attr->extra->encap_subtlvs = NULL;
 
 278  * Compare encap sub-tlv chains
 
 283  * This algorithm could be made faster if needed
 
 286 encap_same(struct bgp_attr_encap_subtlv *h1, struct bgp_attr_encap_subtlv *h2)
 
 288     struct bgp_attr_encap_subtlv *p;
 
 289     struct bgp_attr_encap_subtlv *q;
 
 300     for (p = h1; p; p = p->next) {
 
 301         for (q = h2; q; q = q->next) {
 
 302             if ((p->type == q->type) &&
 
 303                 (p->length == q->length) &&
 
 304                 !memcmp(p->value, q->value, p->length)) {
 
 313     for (p = h2; p; p = p->next) {
 
 314         for (q = h1; q; q = q->next) {
 
 315             if ((p->type == q->type) &&
 
 316                 (p->length == q->length) &&
 
 317                 !memcmp(p->value, q->value, p->length)) {
 
 329 /* Unknown transit attribute. */
 
 330 static struct hash *transit_hash;
 
 333 transit_free (struct transit *transit)
 
 336     XFREE (MTYPE_TRANSIT_VAL, transit->val);
 
 337   XFREE (MTYPE_TRANSIT, transit);
 
 342 transit_hash_alloc (void *p)
 
 344   /* Transit structure is already allocated.  */
 
 348 static struct transit *
 
 349 transit_intern (struct transit *transit)
 
 351   struct transit *find;
 
 353   find = hash_get (transit_hash, transit, transit_hash_alloc);
 
 355     transit_free (transit);
 
 362 transit_unintern (struct transit **transit)
 
 364   struct transit *t = *transit;
 
 371       hash_release (transit_hash, t);
 
 378 transit_hash_key_make (void *p)
 
 380   const struct transit * transit = p;
 
 382   return jhash(transit->val, transit->length, 0);
 
 386 transit_hash_cmp (const void *p1, const void *p2)
 
 388   const struct transit * transit1 = p1;
 
 389   const struct transit * transit2 = p2;
 
 391   return (transit1->length == transit2->length &&
 
 392           memcmp (transit1->val, transit2->val, transit1->length) == 0);
 
 398   transit_hash = hash_create (transit_hash_key_make, transit_hash_cmp);
 
 402 transit_finish (void)
 
 404   hash_clean (transit_hash, (void (*)(void *))transit_free);
 
 405   hash_free (transit_hash);
 
 409 /* Attribute hash routines. */
 
 410 static struct hash *attrhash;
 
 412 static struct attr_extra *
 
 413 bgp_attr_extra_new (void)
 
 415   return XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra));
 
 419 bgp_attr_extra_free (struct attr *attr)
 
 423       if (attr->extra->encap_subtlvs) {
 
 424         encap_free(attr->extra->encap_subtlvs);
 
 425         attr->extra->encap_subtlvs = NULL;
 
 427       XFREE (MTYPE_ATTR_EXTRA, attr->extra);
 
 433 bgp_attr_extra_get (struct attr *attr)
 
 436     attr->extra = bgp_attr_extra_new();
 
 440 /* Shallow copy of an attribute
 
 441  * Though, not so shallow that it doesn't copy the contents
 
 442  * of the attr_extra pointed to by 'extra'
 
 445 bgp_attr_dup (struct attr *new, struct attr *orig)
 
 447   struct attr_extra *extra = new->extra;
 
 450   /* if caller provided attr_extra space, use it in any case.
 
 452    * This is neccesary even if orig->extra equals NULL, because otherwise
 
 453    * memory may be later allocated on the heap by bgp_attr_extra_get.
 
 455    * That memory would eventually be leaked, because the caller must not
 
 456    * call bgp_attr_extra_free if he provided attr_extra on the stack.
 
 461       memset(new->extra, 0, sizeof(struct attr_extra));
 
 463         *new->extra = *orig->extra;
 
 464         if (orig->extra->encap_subtlvs) {
 
 465           new->extra->encap_subtlvs = encap_tlv_dup(orig->extra->encap_subtlvs);
 
 469   else if (orig->extra)
 
 471       new->extra = bgp_attr_extra_new();
 
 472       *new->extra = *orig->extra;
 
 473       if (orig->extra->encap_subtlvs) {
 
 474         new->extra->encap_subtlvs = encap_tlv_dup(orig->extra->encap_subtlvs);
 
 482   return attrhash->count;
 
 486 attr_unknown_count (void)
 
 488   return transit_hash->count;
 
 492 attrhash_key_make (void *p)
 
 494   const struct attr *attr = (struct attr *) p;
 
 495   const struct attr_extra *extra = attr->extra;
 
 497 #define MIX(val)        key = jhash_1word(val, key)
 
 500   MIX(attr->nexthop.s_addr);
 
 502   MIX(attr->local_pref);
 
 505   key += attr->nexthop.s_addr;
 
 507   key += attr->local_pref;
 
 511       MIX(extra->aggregator_as);
 
 512       MIX(extra->aggregator_addr.s_addr);
 
 514       MIX(extra->mp_nexthop_global_in.s_addr);
 
 515       MIX(extra->originator_id.s_addr);
 
 520     MIX(aspath_key_make (attr->aspath));
 
 522     MIX(community_hash_make (attr->community));
 
 526       if (extra->lcommunity)
 
 527         MIX(lcommunity_hash_make (extra->lcommunity));
 
 528       if (extra->ecommunity)
 
 529         MIX(ecommunity_hash_make (extra->ecommunity));
 
 531         MIX(cluster_hash_key_make (extra->cluster));
 
 533         MIX(transit_hash_key_make (extra->transit));
 
 535       MIX(extra->mp_nexthop_len);
 
 536       key = jhash(extra->mp_nexthop_global.s6_addr, 16, key);
 
 537       key = jhash(extra->mp_nexthop_local.s6_addr, 16, key);
 
 544 attrhash_cmp (const void *p1, const void *p2)
 
 546   const struct attr * attr1 = p1;
 
 547   const struct attr * attr2 = p2;
 
 549   if (attr1->flag == attr2->flag
 
 550       && attr1->origin == attr2->origin
 
 551       && attr1->nexthop.s_addr == attr2->nexthop.s_addr
 
 552       && attr1->aspath == attr2->aspath
 
 553       && attr1->community == attr2->community
 
 554       && attr1->med == attr2->med
 
 555       && attr1->local_pref == attr2->local_pref)
 
 557       const struct attr_extra *ae1 = attr1->extra;
 
 558       const struct attr_extra *ae2 = attr2->extra;
 
 561           && ae1->aggregator_as == ae2->aggregator_as
 
 562           && ae1->aggregator_addr.s_addr == ae2->aggregator_addr.s_addr
 
 563           && ae1->weight == ae2->weight
 
 564           && ae1->tag == ae2->tag
 
 565           && ae1->mp_nexthop_len == ae2->mp_nexthop_len
 
 566           && IPV6_ADDR_SAME (&ae1->mp_nexthop_global, &ae2->mp_nexthop_global)
 
 567           && IPV6_ADDR_SAME (&ae1->mp_nexthop_local, &ae2->mp_nexthop_local)
 
 568           && IPV4_ADDR_SAME (&ae1->mp_nexthop_global_in, &ae2->mp_nexthop_global_in)
 
 569           && ae1->ecommunity == ae2->ecommunity
 
 570           && ae1->lcommunity == ae2->lcommunity
 
 571           && ae1->cluster == ae2->cluster
 
 572           && ae1->transit == ae2->transit
 
 573           && (ae1->encap_tunneltype == ae2->encap_tunneltype)
 
 574           && encap_same(ae1->encap_subtlvs, ae2->encap_subtlvs)
 
 575           && IPV4_ADDR_SAME (&ae1->originator_id, &ae2->originator_id))
 
 579       /* neither attribute has extra attributes, so they're same */
 
 589   attrhash = hash_create (attrhash_key_make, attrhash_cmp);
 
 593  * special for hash_clean below
 
 596 attr_vfree (void *attr)
 
 598   bgp_attr_extra_free ((struct attr *)attr);
 
 599   XFREE (MTYPE_ATTR, attr);
 
 603 attrhash_finish (void)
 
 605   hash_clean(attrhash, attr_vfree);
 
 606   hash_free (attrhash);
 
 611 attr_show_all_iterator (struct hash_backet *backet, struct vty *vty)
 
 613   struct attr *attr = backet->data;
 
 615   vty_out (vty, "attr[%ld] nexthop %s%s", attr->refcnt, 
 
 616            inet_ntoa (attr->nexthop), VTY_NEWLINE);
 
 620 attr_show_all (struct vty *vty)
 
 622   hash_iterate (attrhash, 
 
 623                 (void (*)(struct hash_backet *, void *))
 
 624                 attr_show_all_iterator,
 
 629 bgp_attr_hash_alloc (void *p)
 
 631   struct attr * val = (struct attr *) p;
 
 634   attr = XMALLOC (MTYPE_ATTR, sizeof (struct attr));
 
 638       attr->extra = bgp_attr_extra_new ();
 
 639       *attr->extra = *val->extra;
 
 641       if (attr->extra->encap_subtlvs) {
 
 642         attr->extra->encap_subtlvs = encap_tlv_dup(attr->extra->encap_subtlvs);
 
 649 /* Internet argument attribute. */
 
 651 bgp_attr_intern (struct attr *attr)
 
 655   /* Intern referenced strucutre. */
 
 658       if (! attr->aspath->refcnt)
 
 659         attr->aspath = aspath_intern (attr->aspath);
 
 661         attr->aspath->refcnt++;
 
 665       if (! attr->community->refcnt)
 
 666         attr->community = community_intern (attr->community);
 
 668         attr->community->refcnt++;
 
 672       struct attr_extra *attre = attr->extra;
 
 674       if (attre->ecommunity)
 
 676           if (! attre->ecommunity->refcnt)
 
 677             attre->ecommunity = ecommunity_intern (attre->ecommunity);
 
 679             attre->ecommunity->refcnt++;
 
 682       if (attre->lcommunity)
 
 684           if (! attre->lcommunity->refcnt)
 
 685             attre->lcommunity = lcommunity_intern (attre->lcommunity);
 
 687             attre->lcommunity->refcnt++;
 
 691           if (! attre->cluster->refcnt)
 
 692             attre->cluster = cluster_intern (attre->cluster);
 
 694             attre->cluster->refcnt++;
 
 698           if (! attre->transit->refcnt)
 
 699             attre->transit = transit_intern (attre->transit);
 
 701             attre->transit->refcnt++;
 
 705   find = (struct attr *) hash_get (attrhash, attr, bgp_attr_hash_alloc);
 
 712 /* Make network statement's attribute. */
 
 714 bgp_attr_default_set (struct attr *attr, u_char origin)
 
 716   memset (attr, 0, sizeof (struct attr));
 
 717   bgp_attr_extra_get (attr);
 
 719   attr->origin = origin;
 
 720   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);
 
 721   attr->aspath = aspath_empty ();
 
 722   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
 
 723   attr->extra->weight = BGP_ATTR_DEFAULT_WEIGHT;
 
 724   attr->extra->tag = 0;
 
 725   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
 
 726   attr->extra->mp_nexthop_len = IPV6_MAX_BYTELEN;
 
 732 /* Make network statement's attribute. */
 
 734 bgp_attr_default_intern (u_char origin)
 
 739   memset (&attr, 0, sizeof (struct attr));
 
 740   bgp_attr_extra_get (&attr);
 
 742   bgp_attr_default_set(&attr, origin);
 
 744   new = bgp_attr_intern (&attr);
 
 745   bgp_attr_extra_free (&attr);
 
 747   aspath_unintern (&new->aspath);
 
 751 /* Create the attributes for an aggregate */
 
 753 bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin,
 
 754                            struct aspath *aspath,
 
 755                            struct community *community, int as_set,
 
 756                            u_char atomic_aggregate)
 
 760   struct attr_extra attre;
 
 762   memset (&attr, 0, sizeof (struct attr));
 
 763   memset (&attre, 0, sizeof (struct attr_extra));
 
 766   /* Origin attribute. */
 
 767   attr.origin = origin;
 
 768   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);
 
 770   /* AS path attribute. */
 
 772     attr.aspath = aspath_intern (aspath);
 
 774     attr.aspath = aspath_empty ();
 
 775   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
 
 777   /* Next hop attribute.  */
 
 778   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
 
 782       attr.community = community;
 
 783       attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
 
 786   attre.weight = BGP_ATTR_DEFAULT_WEIGHT;
 
 787   attre.mp_nexthop_len = IPV6_MAX_BYTELEN;
 
 789   if (! as_set || atomic_aggregate)
 
 790     attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
 
 791   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
 
 792   if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
 
 793     attre.aggregator_as = bgp->confed_id;
 
 795     attre.aggregator_as = bgp->as;
 
 796   attre.aggregator_addr = bgp->router_id;
 
 798   new = bgp_attr_intern (&attr);
 
 800   aspath_unintern (&new->aspath);
 
 804 /* Unintern just the sub-components of the attr, but not the attr */
 
 806 bgp_attr_unintern_sub (struct attr *attr)
 
 808   /* aspath refcount shoud be decrement. */
 
 810     aspath_unintern (&attr->aspath);
 
 811   UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH));
 
 814     community_unintern (&attr->community);
 
 815   UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
 
 819       if (attr->extra->ecommunity)
 
 820         ecommunity_unintern (&attr->extra->ecommunity);
 
 821       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES));
 
 823       if (attr->extra->lcommunity)
 
 824         lcommunity_unintern (&attr->extra->lcommunity);
 
 825       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
 
 827       if (attr->extra->cluster)
 
 828         cluster_unintern (&attr->extra->cluster);
 
 829       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST));
 
 831       if (attr->extra->transit)
 
 832         transit_unintern (&attr->extra->transit);
 
 836 /* Free bgp attribute and aspath. */
 
 838 bgp_attr_unintern (struct attr **pattr)
 
 840   struct attr *attr = *pattr;
 
 843   struct attr_extra tmp_extra;
 
 845   /* Decrement attribute reference. */
 
 852       tmp.extra = &tmp_extra;
 
 853       memcpy (tmp.extra, attr->extra, sizeof (struct attr_extra));
 
 856   /* If reference becomes zero then free attribute object. */
 
 857   if (attr->refcnt == 0)
 
 859       ret = hash_release (attrhash, attr);
 
 860       assert (ret != NULL);
 
 861       bgp_attr_extra_free (attr);
 
 862       XFREE (MTYPE_ATTR, attr);
 
 866   bgp_attr_unintern_sub (&tmp);
 
 870 bgp_attr_flush (struct attr *attr)
 
 872   if (attr->aspath && ! attr->aspath->refcnt)
 
 874       aspath_free (attr->aspath);
 
 877   if (attr->community && ! attr->community->refcnt)
 
 879       community_free (attr->community);
 
 880       attr->community = NULL;
 
 884       struct attr_extra *attre = attr->extra;
 
 886       if (attre->ecommunity && ! attre->ecommunity->refcnt)
 
 887         ecommunity_free (&attre->ecommunity);
 
 888       if (attre->lcommunity && ! attre->lcommunity->refcnt)
 
 889         lcommunity_free (&attre->lcommunity);
 
 890       if (attre->cluster && ! attre->cluster->refcnt)
 
 892           cluster_free (attre->cluster);
 
 893           attre->cluster = NULL;
 
 895       if (attre->transit && ! attre->transit->refcnt)
 
 897           transit_free (attre->transit);
 
 898           attre->transit = NULL;
 
 900       encap_free(attre->encap_subtlvs);
 
 901       attre->encap_subtlvs = NULL;
 
 905 /* Implement some draft-ietf-idr-error-handling behaviour and
 
 906  * avoid resetting sessions for malformed attributes which are
 
 907  * are partial/optional and hence where the error likely was not
 
 908  * introduced by the sending neighbour.
 
 910 static bgp_attr_parse_ret_t
 
 911 bgp_attr_malformed (struct bgp_attr_parser_args *args, u_char subcode,
 
 914   struct peer *const peer = args->peer; 
 
 915   const u_int8_t flags = args->flags;
 
 916   /* startp and length must be special-cased, as whether or not to
 
 917    * send the attribute data with the NOTIFY depends on the error,
 
 918    * the caller therefore signals this with the seperate length argument
 
 920   u_char *notify_datap = (length > 0 ? args->startp : NULL);
 
 922   /* The malformed attribute shouldn't be passed on, should
 
 923    * we decide to proceed with parsing the UPDATE
 
 925   UNSET_FLAG (args->attr->flag,  ATTR_FLAG_BIT (args->type));
 
 927   /* Only relax error handling for eBGP peers */
 
 928   if (peer->sort != BGP_PEER_EBGP)
 
 930       bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, subcode,
 
 931                                  notify_datap, length);
 
 932       return BGP_ATTR_PARSE_ERROR;
 
 936   /* Adjust the stream getp to the end of the attribute, in case we can
 
 937    * still proceed but the caller hasn't read all the attribute.
 
 939   stream_set_getp (BGP_INPUT (peer),
 
 940                    (args->startp - STREAM_DATA (BGP_INPUT (peer)))
 
 943   switch (args->type) {
 
 944     /* where an attribute is relatively inconsequential, e.g. it does not
 
 945      * affect route selection, and can be safely ignored, then any such
 
 946      * attributes which are malformed should just be ignored and the route
 
 947      * processed as normal.
 
 949     case BGP_ATTR_AS4_AGGREGATOR:
 
 950     case BGP_ATTR_AGGREGATOR:
 
 951     case BGP_ATTR_ATOMIC_AGGREGATE:
 
 952       return BGP_ATTR_PARSE_PROCEED;
 
 954     /* Core attributes, particularly ones which may influence route
 
 955      * selection, should always cause session resets
 
 957     case BGP_ATTR_ORIGIN:
 
 958     case BGP_ATTR_AS_PATH:
 
 959     case BGP_ATTR_NEXT_HOP:
 
 960     case BGP_ATTR_MULTI_EXIT_DISC:
 
 961     case BGP_ATTR_LOCAL_PREF:
 
 962     case BGP_ATTR_COMMUNITIES:
 
 963     case BGP_ATTR_ORIGINATOR_ID:
 
 964     case BGP_ATTR_CLUSTER_LIST:
 
 965     case BGP_ATTR_MP_REACH_NLRI:
 
 966     case BGP_ATTR_MP_UNREACH_NLRI:
 
 967     case BGP_ATTR_EXT_COMMUNITIES:
 
 968       bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, subcode,
 
 969                                  notify_datap, length);
 
 970       return BGP_ATTR_PARSE_ERROR;
 
 973   /* Partial optional attributes that are malformed should not cause
 
 974    * the whole session to be reset. Instead treat it as a withdrawal
 
 975    * of the routes, if possible.
 
 977   if (CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS)
 
 978       && CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
 
 979       && CHECK_FLAG (flags, BGP_ATTR_FLAG_PARTIAL))
 
 980     return BGP_ATTR_PARSE_WITHDRAW;
 
 982   /* default to reset */
 
 983   bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, subcode,
 
 984                              notify_datap, length);
 
 985   return BGP_ATTR_PARSE_ERROR;
 
 988 /* Find out what is wrong with the path attribute flag bits and log the error.
 
 989    "Flag bits" here stand for Optional, Transitive and Partial, but not for
 
 990    Extended Length. Checking O/T/P bits at once implies, that the attribute
 
 991    being diagnosed is defined by RFC as either a "well-known" or an "optional,
 
 992    non-transitive" attribute. */
 
 994 bgp_attr_flags_diagnose (struct bgp_attr_parser_args *args,
 
 995                          u_int8_t desired_flags /* how RFC says it must be */
 
 999   u_char real_flags = args->flags;
 
1000   const u_int8_t attr_code = args->type;
 
1002   desired_flags &= ~BGP_ATTR_FLAG_EXTLEN;
 
1003   real_flags &= ~BGP_ATTR_FLAG_EXTLEN;
 
1004   for (i = 0; i <= 2; i++) /* O,T,P, but not E */
 
1007       CHECK_FLAG (desired_flags, attr_flag_str[i].key) !=
 
1008       CHECK_FLAG (real_flags,    attr_flag_str[i].key)
 
1011       zlog (args->peer->log, LOG_ERR, "%s attribute must%s be flagged as \"%s\"",
 
1012             LOOKUP (attr_str, attr_code),
 
1013             CHECK_FLAG (desired_flags, attr_flag_str[i].key) ? "" : " not",
 
1014             attr_flag_str[i].str);
 
1019       zlog (args->peer->log, LOG_DEBUG,
 
1020             "Strange, %s called for attr %s, but no problem found with flags"
 
1021             " (real flags 0x%x, desired 0x%x)",
 
1022             __func__, LOOKUP (attr_str, attr_code),
 
1023             real_flags, desired_flags);
 
1027 /* Required flags for attributes. EXTLEN will be masked off when testing,
 
1028  * as will PARTIAL for optional+transitive attributes.
 
1030 const u_int8_t attr_flags_values [] = {
 
1031   [BGP_ATTR_ORIGIN] =           BGP_ATTR_FLAG_TRANS,
 
1032   [BGP_ATTR_AS_PATH] =          BGP_ATTR_FLAG_TRANS,
 
1033   [BGP_ATTR_NEXT_HOP] =         BGP_ATTR_FLAG_TRANS,
 
1034   [BGP_ATTR_MULTI_EXIT_DISC] =  BGP_ATTR_FLAG_OPTIONAL,
 
1035   [BGP_ATTR_LOCAL_PREF] =       BGP_ATTR_FLAG_TRANS,
 
1036   [BGP_ATTR_ATOMIC_AGGREGATE] = BGP_ATTR_FLAG_TRANS,
 
1037   [BGP_ATTR_AGGREGATOR] =       BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
 
1038   [BGP_ATTR_COMMUNITIES] =      BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
 
1039   [BGP_ATTR_ORIGINATOR_ID] =    BGP_ATTR_FLAG_OPTIONAL,
 
1040   [BGP_ATTR_CLUSTER_LIST] =     BGP_ATTR_FLAG_OPTIONAL,
 
1041   [BGP_ATTR_MP_REACH_NLRI] =    BGP_ATTR_FLAG_OPTIONAL,
 
1042   [BGP_ATTR_MP_UNREACH_NLRI] =  BGP_ATTR_FLAG_OPTIONAL,
 
1043   [BGP_ATTR_EXT_COMMUNITIES] =  BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
 
1044   [BGP_ATTR_AS4_PATH] =         BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
 
1045   [BGP_ATTR_AS4_AGGREGATOR] =   BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
 
1046   [BGP_ATTR_LARGE_COMMUNITIES] = BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
 
1048 static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
 
1051 bgp_attr_flag_invalid (struct bgp_attr_parser_args *args)
 
1053   u_int8_t mask = BGP_ATTR_FLAG_EXTLEN;
 
1054   const u_int8_t flags = args->flags;
 
1055   const u_int8_t attr_code = args->type;
 
1056   struct peer *const peer = args->peer; 
 
1058   /* there may be attributes we don't know about */
 
1059   if (attr_code > attr_flags_values_max)
 
1061   if (attr_flags_values[attr_code] == 0)
 
1064   /* RFC4271, "For well-known attributes, the Transitive bit MUST be set to
 
1067   if (!CHECK_FLAG (BGP_ATTR_FLAG_OPTIONAL, flags)
 
1068       && !CHECK_FLAG (BGP_ATTR_FLAG_TRANS, flags))
 
1070       zlog (peer->log, LOG_ERR,
 
1071             "%s well-known attributes must have transitive flag set (%x)",
 
1072             LOOKUP (attr_str, attr_code), flags);
 
1076   /* "For well-known attributes and for optional non-transitive attributes,
 
1077    *  the Partial bit MUST be set to 0." 
 
1079   if (CHECK_FLAG (flags, BGP_ATTR_FLAG_PARTIAL))
 
1081       if (!CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL))
 
1083           zlog (peer->log, LOG_ERR,
 
1084                 "%s well-known attribute "
 
1085                 "must NOT have the partial flag set (%x)",
 
1086                  LOOKUP (attr_str, attr_code), flags);
 
1089       if (CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
 
1090           && !CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS))
 
1092           zlog (peer->log, LOG_ERR,
 
1093                 "%s optional + transitive attribute "
 
1094                 "must NOT have the partial flag set (%x)",
 
1095                  LOOKUP (attr_str, attr_code), flags);
 
1100   /* Optional transitive attributes may go through speakers that don't
 
1101    * reocgnise them and set the Partial bit.
 
1103   if (CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
 
1104       && CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS))
 
1105     SET_FLAG (mask, BGP_ATTR_FLAG_PARTIAL);
 
1108       == attr_flags_values[attr_code])
 
1111   bgp_attr_flags_diagnose (args, attr_flags_values[attr_code]);
 
1115 /* Get origin attribute of the update message. */
 
1116 static bgp_attr_parse_ret_t
 
1117 bgp_attr_origin (struct bgp_attr_parser_args *args)
 
1119   struct peer *const peer = args->peer;
 
1120   struct attr *const attr = args->attr;
 
1121   const bgp_size_t length = args->length;
 
1123   /* If any recognized attribute has Attribute Length that conflicts
 
1124      with the expected length (based on the attribute type code), then
 
1125      the Error Subcode is set to Attribute Length Error.  The Data
 
1126      field contains the erroneous attribute (type, length and
 
1130       zlog (peer->log, LOG_ERR, "Origin attribute length is not one %d",
 
1132       return bgp_attr_malformed (args,
 
1133                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
1137   /* Fetch origin attribute. */
 
1138   attr->origin = stream_getc (BGP_INPUT (peer));
 
1140   /* If the ORIGIN attribute has an undefined value, then the Error
 
1141      Subcode is set to Invalid Origin Attribute.  The Data field
 
1142      contains the unrecognized attribute (type, length and value). */
 
1143   if ((attr->origin != BGP_ORIGIN_IGP)
 
1144       && (attr->origin != BGP_ORIGIN_EGP)
 
1145       && (attr->origin != BGP_ORIGIN_INCOMPLETE))
 
1147       zlog (peer->log, LOG_ERR, "Origin attribute value is invalid %d",
 
1149       return bgp_attr_malformed (args,
 
1150                                  BGP_NOTIFY_UPDATE_INVAL_ORIGIN,
 
1154   /* Set oring attribute flag. */
 
1155   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);
 
1160 /* Parse AS path information.  This function is wrapper of
 
1163 bgp_attr_aspath (struct bgp_attr_parser_args *args)
 
1165   struct attr *const attr = args->attr;
 
1166   struct peer *const peer = args->peer; 
 
1167   const bgp_size_t length = args->length;
 
1170    * peer with AS4 => will get 4Byte ASnums
 
1171    * otherwise, will get 16 Bit
 
1173   attr->aspath = aspath_parse (peer->ibuf, length, 
 
1174                                CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV));
 
1176   /* In case of IBGP, length will be zero. */
 
1179       zlog (peer->log, LOG_ERR,
 
1180             "Malformed AS path from %s, length is %d",
 
1181             peer->host, length);
 
1182       return bgp_attr_malformed (args, BGP_NOTIFY_UPDATE_MAL_AS_PATH, 0);
 
1185   /* Set aspath attribute flag. */
 
1186   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
 
1188   return BGP_ATTR_PARSE_PROCEED;
 
1191 static bgp_attr_parse_ret_t
 
1192 bgp_attr_aspath_check (struct peer *const peer, struct attr *const attr)
 
1194   /* These checks were part of bgp_attr_aspath, but with
 
1195    * as4 we should to check aspath things when
 
1196    * aspath synthesizing with as4_path has already taken place.
 
1197    * Otherwise we check ASPATH and use the synthesized thing, and that is
 
1199    * So do the checks later, i.e. here
 
1201   struct bgp *bgp = peer->bgp;
 
1202   struct aspath *aspath;
 
1204   /* Confederation sanity check. */
 
1205   if ((peer->sort == BGP_PEER_CONFED && ! aspath_left_confed_check (attr->aspath)) ||
 
1206      (peer->sort == BGP_PEER_EBGP && aspath_confed_check (attr->aspath)))
 
1208       zlog (peer->log, LOG_ERR, "Malformed AS path from %s", peer->host);
 
1209       bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
 
1210                        BGP_NOTIFY_UPDATE_MAL_AS_PATH);
 
1211       return BGP_ATTR_PARSE_ERROR;
 
1214   /* First AS check for EBGP. */
 
1215   if (bgp != NULL && bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
 
1217       if (peer->sort == BGP_PEER_EBGP
 
1218           && ! aspath_firstas_check (attr->aspath, peer->as))
 
1220           zlog (peer->log, LOG_ERR,
 
1221                 "%s incorrect first AS (must be %u)", peer->host, peer->as);
 
1222           bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
 
1223                            BGP_NOTIFY_UPDATE_MAL_AS_PATH);
 
1224           return BGP_ATTR_PARSE_ERROR;
 
1228   /* local-as prepend */
 
1229   if (peer->change_local_as &&
 
1230       ! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
 
1232       aspath = aspath_dup (attr->aspath);
 
1233       aspath = aspath_add_seq (aspath, peer->change_local_as);
 
1234       aspath_unintern (&attr->aspath);
 
1235       attr->aspath = aspath_intern (aspath);
 
1238   return BGP_ATTR_PARSE_PROCEED;
 
1241 /* Parse AS4 path information.  This function is another wrapper of
 
1244 bgp_attr_as4_path (struct bgp_attr_parser_args *args, struct aspath **as4_path)
 
1246   struct peer *const peer = args->peer; 
 
1247   struct attr *const attr = args->attr;
 
1248   const bgp_size_t length = args->length;
 
1250   *as4_path = aspath_parse (peer->ibuf, length, 1);
 
1252   /* In case of IBGP, length will be zero. */
 
1255       zlog (peer->log, LOG_ERR,
 
1256             "Malformed AS4 path from %s, length is %d",
 
1257             peer->host, length);
 
1258       return bgp_attr_malformed (args,
 
1259                                  BGP_NOTIFY_UPDATE_MAL_AS_PATH,
 
1263   /* Set aspath attribute flag. */
 
1265     attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
 
1267   return BGP_ATTR_PARSE_PROCEED;
 
1270 /* Nexthop attribute. */
 
1271 static bgp_attr_parse_ret_t
 
1272 bgp_attr_nexthop (struct bgp_attr_parser_args *args)
 
1274   struct peer *const peer = args->peer; 
 
1275   struct attr *const attr = args->attr;
 
1276   const bgp_size_t length = args->length;
 
1278   in_addr_t nexthop_h, nexthop_n;
 
1280   /* Check nexthop attribute length. */
 
1283       zlog (peer->log, LOG_ERR, "Nexthop attribute length isn't four [%d]",
 
1286       return bgp_attr_malformed (args,
 
1287                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
1291   /* According to section 6.3 of RFC4271, syntactically incorrect NEXT_HOP
 
1292      attribute must result in a NOTIFICATION message (this is implemented below).
 
1293      At the same time, semantically incorrect NEXT_HOP is more likely to be just
 
1294      logged locally (this is implemented somewhere else). The UPDATE message
 
1295      gets ignored in any of these cases. */
 
1296   nexthop_n = stream_get_ipv4 (peer->ibuf);
 
1297   nexthop_h = ntohl (nexthop_n);
 
1298   if ((IPV4_NET0 (nexthop_h) || IPV4_NET127 (nexthop_h) || IPV4_CLASS_DE (nexthop_h))
 
1299       && !BGP_DEBUG (allow_martians, ALLOW_MARTIANS)) /* loopbacks may be used in testing */
 
1301       char buf[INET_ADDRSTRLEN];
 
1302       inet_ntop (AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN);
 
1303       zlog (peer->log, LOG_ERR, "Martian nexthop %s", buf);
 
1304       return bgp_attr_malformed (args,
 
1305                                  BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP,
 
1309   attr->nexthop.s_addr = nexthop_n;
 
1310   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
 
1312   return BGP_ATTR_PARSE_PROCEED;
 
1315 /* MED atrribute. */
 
1316 static bgp_attr_parse_ret_t
 
1317 bgp_attr_med (struct bgp_attr_parser_args *args)
 
1319   struct peer *const peer = args->peer; 
 
1320   struct attr *const attr = args->attr;
 
1321   const bgp_size_t length = args->length;
 
1326       zlog (peer->log, LOG_ERR, 
 
1327             "MED attribute length isn't four [%d]", length);
 
1329       return bgp_attr_malformed (args,
 
1330                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
1334   attr->med = stream_getl (peer->ibuf);
 
1336   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
 
1338   return BGP_ATTR_PARSE_PROCEED;
 
1341 /* Local preference attribute. */
 
1342 static bgp_attr_parse_ret_t
 
1343 bgp_attr_local_pref (struct bgp_attr_parser_args *args)
 
1345   struct peer *const peer = args->peer; 
 
1346   struct attr *const attr = args->attr;
 
1347   const bgp_size_t length = args->length;
 
1352     zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute length isn't 4 [%u]",
 
1354     return bgp_attr_malformed (args,
 
1355                                BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
1359   /* If it is contained in an UPDATE message that is received from an
 
1360      external peer, then this attribute MUST be ignored by the
 
1361      receiving speaker. */
 
1362   if (peer->sort == BGP_PEER_EBGP)
 
1364       stream_forward_getp (peer->ibuf, length);
 
1365       return BGP_ATTR_PARSE_PROCEED;
 
1368   attr->local_pref = stream_getl (peer->ibuf);
 
1370   /* Set atomic aggregate flag. */
 
1371   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
 
1373   return BGP_ATTR_PARSE_PROCEED;
 
1376 /* Atomic aggregate. */
 
1378 bgp_attr_atomic (struct bgp_attr_parser_args *args)
 
1380   struct peer *const peer = args->peer; 
 
1381   struct attr *const attr = args->attr;
 
1382   const bgp_size_t length = args->length;
 
1387       zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute length isn't 0 [%u]",
 
1389       return bgp_attr_malformed (args,
 
1390                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
1394   /* Set atomic aggregate flag. */
 
1395   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
 
1397   return BGP_ATTR_PARSE_PROCEED;
 
1400 /* Aggregator attribute */
 
1402 bgp_attr_aggregator (struct bgp_attr_parser_args *args)
 
1404   struct peer *const peer = args->peer; 
 
1405   struct attr *const attr = args->attr;
 
1406   const bgp_size_t length = args->length;
 
1409   struct attr_extra *attre = bgp_attr_extra_get (attr);
 
1411   /* peer with AS4 will send 4 Byte AS, peer without will send 2 Byte */
 
1412   if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV))
 
1415   if (length != wantedlen)
 
1417       zlog (peer->log, LOG_ERR, "AGGREGATOR attribute length isn't %u [%u]",
 
1419       return bgp_attr_malformed (args,
 
1420                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
1424   if ( CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV ) )
 
1425     attre->aggregator_as = stream_getl (peer->ibuf);
 
1427     attre->aggregator_as = stream_getw (peer->ibuf);
 
1428   attre->aggregator_addr.s_addr = stream_get_ipv4 (peer->ibuf);
 
1430   /* Set atomic aggregate flag. */
 
1431   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
 
1433   return BGP_ATTR_PARSE_PROCEED;
 
1436 /* New Aggregator attribute */
 
1437 static bgp_attr_parse_ret_t
 
1438 bgp_attr_as4_aggregator (struct bgp_attr_parser_args *args,
 
1439                          as_t *as4_aggregator_as,
 
1440                          struct in_addr *as4_aggregator_addr)
 
1442   struct peer *const peer = args->peer; 
 
1443   struct attr *const attr = args->attr;
 
1444   const bgp_size_t length = args->length;
 
1448       zlog (peer->log, LOG_ERR, "New Aggregator length is not 8 [%d]",
 
1450       return bgp_attr_malformed (args,
 
1451                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
1455   *as4_aggregator_as = stream_getl (peer->ibuf);
 
1456   as4_aggregator_addr->s_addr = stream_get_ipv4 (peer->ibuf);
 
1458   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_AGGREGATOR);
 
1460   return BGP_ATTR_PARSE_PROCEED;
 
1463 /* Munge Aggregator and New-Aggregator, AS_PATH and NEW_AS_PATH.
 
1465 static bgp_attr_parse_ret_t
 
1466 bgp_attr_munge_as4_attrs (struct peer *const peer,
 
1467                           struct attr *const attr,
 
1468                           struct aspath *as4_path, as_t as4_aggregator,
 
1469                           struct in_addr *as4_aggregator_addr)
 
1471   int ignore_as4_path = 0;
 
1472   struct aspath *newpath;
 
1473   struct attr_extra *attre = attr->extra;
 
1477       /* NULL aspath shouldn't be possible as bgp_attr_parse should have
 
1478        * checked that all well-known, mandatory attributes were present.
 
1480        * Can only be a problem with peer itself - hard error
 
1482       return BGP_ATTR_PARSE_ERROR;
 
1485   if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV))
 
1487       /* peer can do AS4, so we ignore AS4_PATH and AS4_AGGREGATOR
 
1489        * It is worth a warning though, because the peer really
 
1490        * should not send them
 
1492       if (BGP_DEBUG(as4, AS4))
 
1494           if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))
 
1495             zlog_debug ("[AS4] %s %s AS4_PATH",
 
1496                         peer->host, "AS4 capable peer, yet it sent");
 
1498           if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR)))
 
1499             zlog_debug ("[AS4] %s %s AS4_AGGREGATOR",
 
1500                         peer->host, "AS4 capable peer, yet it sent");
 
1503       return BGP_ATTR_PARSE_PROCEED;
 
1506   /* We have a asn16 peer.  First, look for AS4_AGGREGATOR
 
1507    * because that may override AS4_PATH
 
1509   if (attr->flag & (ATTR_FLAG_BIT (BGP_ATTR_AS4_AGGREGATOR) ) )
 
1511       if (attr->flag & (ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR) ) )
 
1516            * if the as_number in aggregator is not AS_TRANS,
 
1517            *  then AS4_AGGREGATOR and AS4_PATH shall be ignored
 
1518            *        and the Aggregator shall be taken as 
 
1519            *        info on the aggregating node, and the AS_PATH
 
1520            *        shall be taken as the AS_PATH
 
1522            *        the Aggregator shall be ignored and the
 
1523            *        AS4_AGGREGATOR shall be taken as the
 
1524            *        Aggregating node and the AS_PATH is to be
 
1525            *        constructed "as in all other cases"
 
1527           if (attre->aggregator_as != BGP_AS_TRANS)
 
1530               if ( BGP_DEBUG(as4, AS4))
 
1531                 zlog_debug ("[AS4] %s BGP not AS4 capable peer" 
 
1532                             " send AGGREGATOR != AS_TRANS and"
 
1533                             " AS4_AGGREGATOR, so ignore"
 
1534                             " AS4_AGGREGATOR and AS4_PATH", peer->host);
 
1535               ignore_as4_path = 1;
 
1539               /* "New_aggregator shall be taken as aggregator" */
 
1540               attre->aggregator_as = as4_aggregator;
 
1541               attre->aggregator_addr.s_addr = as4_aggregator_addr->s_addr;
 
1546           /* We received a AS4_AGGREGATOR but no AGGREGATOR.
 
1547            * That is bogus - but reading the conditions
 
1548            * we have to handle AS4_AGGREGATOR as if it were
 
1549            * AGGREGATOR in that case
 
1551           if ( BGP_DEBUG(as4, AS4))
 
1552             zlog_debug ("[AS4] %s BGP not AS4 capable peer send"
 
1553                         " AS4_AGGREGATOR but no AGGREGATOR, will take"
 
1554                         " it as if AGGREGATOR with AS_TRANS had been there", peer->host);
 
1555           (attre = bgp_attr_extra_get (attr))->aggregator_as = as4_aggregator;
 
1556           /* sweep it under the carpet and simulate a "good" AGGREGATOR */
 
1557           attr->flag |= (ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR));
 
1561   /* need to reconcile NEW_AS_PATH and AS_PATH */
 
1562   if (!ignore_as4_path && (attr->flag & (ATTR_FLAG_BIT( BGP_ATTR_AS4_PATH))))
 
1564       newpath = aspath_reconcile_as4 (attr->aspath, as4_path);
 
1565       aspath_unintern (&attr->aspath);
 
1566       attr->aspath = aspath_intern (newpath);
 
1568   return BGP_ATTR_PARSE_PROCEED;
 
1571 /* Community attribute. */
 
1572 static bgp_attr_parse_ret_t
 
1573 bgp_attr_community (struct bgp_attr_parser_args *args)
 
1575   struct peer *const peer = args->peer; 
 
1576   struct attr *const attr = args->attr;  
 
1577   const bgp_size_t length = args->length;
 
1581       attr->community = NULL;
 
1582       return BGP_ATTR_PARSE_PROCEED;
 
1586     community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length);
 
1588   /* XXX: fix community_parse to use stream API and remove this */
 
1589   stream_forward_getp (peer->ibuf, length);
 
1591   if (!attr->community)
 
1592     return bgp_attr_malformed (args,
 
1593                                BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
 
1596   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
 
1598   return BGP_ATTR_PARSE_PROCEED;
 
1601 /* Originator ID attribute. */
 
1602 static bgp_attr_parse_ret_t
 
1603 bgp_attr_originator_id (struct bgp_attr_parser_args *args)
 
1605   struct peer *const peer = args->peer; 
 
1606   struct attr *const attr = args->attr;
 
1607   const bgp_size_t length = args->length;
 
1612       zlog (peer->log, LOG_ERR, "Bad originator ID length %d", length);
 
1614       return bgp_attr_malformed (args,
 
1615                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
1619   (bgp_attr_extra_get (attr))->originator_id.s_addr 
 
1620     = stream_get_ipv4 (peer->ibuf);
 
1622   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
 
1624   return BGP_ATTR_PARSE_PROCEED;
 
1627 /* Cluster list attribute. */
 
1628 static bgp_attr_parse_ret_t
 
1629 bgp_attr_cluster_list (struct bgp_attr_parser_args *args)
 
1631   struct peer *const peer = args->peer; 
 
1632   struct attr *const attr = args->attr;
 
1633   const bgp_size_t length = args->length;
 
1638       zlog (peer->log, LOG_ERR, "Bad cluster list length %d", length);
 
1640       return bgp_attr_malformed (args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
1644   (bgp_attr_extra_get (attr))->cluster 
 
1645     = cluster_parse ((struct in_addr *)stream_pnt (peer->ibuf), length);
 
1647   /* XXX: Fix cluster_parse to use stream API and then remove this */
 
1648   stream_forward_getp (peer->ibuf, length);
 
1650   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST);
 
1652   return BGP_ATTR_PARSE_PROCEED;
 
1655 /* Multiprotocol reachability information parse. */
 
1657 bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
 
1658                     struct bgp_nlri *mp_update)
 
1662   bgp_size_t nlri_len;
 
1665   struct peer *const peer = args->peer;  
 
1666   struct attr *const attr = args->attr;
 
1667   const bgp_size_t length = args->length;
 
1668   struct attr_extra *attre = bgp_attr_extra_get(attr);
 
1670   /* Set end of packet. */
 
1671   s = BGP_INPUT(peer);
 
1672   start = stream_get_getp(s);
 
1674   /* safe to read statically sized header? */
 
1675 #define BGP_MP_REACH_MIN_SIZE 5
 
1676 #define LEN_LEFT        (length - (stream_get_getp(s) - start))
 
1677   if ((length > STREAM_READABLE(s)) || (length < BGP_MP_REACH_MIN_SIZE))
 
1679       zlog_info ("%s: %s sent invalid length, %lu", 
 
1680                  __func__, peer->host, (unsigned long)length);
 
1681       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
 
1684   /* Load AFI, SAFI. */
 
1685   afi = stream_getw (s);
 
1686   safi = stream_getc (s);
 
1688   /* Get nexthop length. */
 
1689   attre->mp_nexthop_len = stream_getc (s);
 
1691   if (LEN_LEFT < attre->mp_nexthop_len)
 
1693       zlog_info ("%s: %s, MP nexthop length, %u, goes past end of attribute", 
 
1694                  __func__, peer->host, attre->mp_nexthop_len);
 
1695       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
 
1698   /* Nexthop length check. */
 
1699   switch (attre->mp_nexthop_len)
 
1702       stream_get (&attre->mp_nexthop_global_in, s, 4);
 
1703       /* Probably needed for RFC 2283 */
 
1704       if (attr->nexthop.s_addr == 0)
 
1705         memcpy(&attr->nexthop.s_addr, &attre->mp_nexthop_global_in, 4);
 
1708       stream_getl (s); /* RD high */
 
1709       stream_getl (s); /* RD low */
 
1710       stream_get (&attre->mp_nexthop_global_in, s, 4);
 
1714         u_int32_t rd_high __attribute__((unused));
 
1715         u_int32_t rd_low __attribute__((unused));
 
1717         rd_high = stream_getl (s);
 
1718         rd_low = stream_getl (s);
 
1722       stream_get (&attre->mp_nexthop_global, s, 16);
 
1726       if (attre->mp_nexthop_len == 48) {
 
1727         u_int32_t rd_high __attribute__((unused));
 
1728         u_int32_t rd_low __attribute__((unused));
 
1730         rd_high = stream_getl (s);
 
1731         rd_low = stream_getl (s);
 
1733       stream_get (&attre->mp_nexthop_global, s, 16);
 
1735       if (attre->mp_nexthop_len == 48) {
 
1736         u_int32_t rd_high __attribute__((unused));
 
1737         u_int32_t rd_low __attribute__((unused));
 
1739         rd_high = stream_getl (s);
 
1740         rd_low = stream_getl (s);
 
1742       stream_get (&attre->mp_nexthop_local, s, 16);
 
1743       if (! IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local))
 
1745           char buf1[INET6_ADDRSTRLEN];
 
1746           char buf2[INET6_ADDRSTRLEN];
 
1748           if (BGP_DEBUG (update, UPDATE_IN))
 
1749             zlog_debug ("%s got two nexthop %s %s but second one is not a link-local nexthop", peer->host,
 
1750                        inet_ntop (AF_INET6, &attre->mp_nexthop_global,
 
1751                                   buf1, INET6_ADDRSTRLEN),
 
1752                        inet_ntop (AF_INET6, &attre->mp_nexthop_local,
 
1753                                   buf2, INET6_ADDRSTRLEN));
 
1755           attre->mp_nexthop_len = 16;
 
1759       zlog_info ("%s: (%s) Wrong multiprotocol next hop length: %d", 
 
1760                  __func__, peer->host, attre->mp_nexthop_len);
 
1761       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
 
1766       zlog_info ("%s: (%s) Failed to read SNPA and NLRI(s)",
 
1767                  __func__, peer->host);
 
1768       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
 
1773     if ((val = stream_getc (s)))
 
1774     zlog_warn ("%s sent non-zero value, %u, for defunct SNPA-length field",
 
1778   /* must have nrli_len, what is left of the attribute */
 
1779   nlri_len = LEN_LEFT;
 
1780   if ((!nlri_len) || (nlri_len > STREAM_READABLE(s)))
 
1782       zlog_info ("%s: (%s) Failed to read NLRI",
 
1783                  __func__, peer->host);
 
1784       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
 
1787   mp_update->afi = afi;
 
1788   mp_update->safi = safi;
 
1789   mp_update->nlri = stream_pnt (s);
 
1790   mp_update->length = nlri_len;
 
1792   stream_forward_getp (s, nlri_len);
 
1794   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MP_REACH_NLRI);
 
1796   return BGP_ATTR_PARSE_PROCEED;
 
1800 /* Multiprotocol unreachable parse */
 
1802 bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
 
1803                       struct bgp_nlri *mp_withdraw)
 
1808   u_int16_t withdraw_len;
 
1809   struct peer *const peer = args->peer;  
 
1810   struct attr *const attr = args->attr;
 
1811   const bgp_size_t length = args->length;
 
1815 #define BGP_MP_UNREACH_MIN_SIZE 3
 
1816   if ((length > STREAM_READABLE(s)) || (length <  BGP_MP_UNREACH_MIN_SIZE))
 
1817     return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
 
1819   afi = stream_getw (s);
 
1820   safi = stream_getc (s);
 
1822   withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
 
1824   mp_withdraw->afi = afi;
 
1825   mp_withdraw->safi = safi;
 
1826   mp_withdraw->nlri = stream_pnt (s);
 
1827   mp_withdraw->length = withdraw_len;
 
1829   stream_forward_getp (s, withdraw_len);
 
1831   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI);
 
1833   return BGP_ATTR_PARSE_PROCEED;
 
1836 /* Large Community attribute. */
 
1837 static bgp_attr_parse_ret_t
 
1838 bgp_attr_large_community (struct bgp_attr_parser_args *args)
 
1840   struct peer *const peer = args->peer;
 
1841   struct attr *const attr = args->attr;
 
1842   const bgp_size_t length = args->length;
 
1847         attr->extra->lcommunity = NULL;
 
1848       /* Empty extcomm doesn't seem to be invalid per se */
 
1849       return BGP_ATTR_PARSE_PROCEED;
 
1852   (bgp_attr_extra_get (attr))->lcommunity =
 
1853     lcommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
 
1854   /* XXX: fix ecommunity_parse to use stream API */
 
1855   stream_forward_getp (peer->ibuf, length);
 
1857   if (attr->extra && !attr->extra->lcommunity)
 
1858     return bgp_attr_malformed (args,
 
1859                                BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
 
1862   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
 
1864   return BGP_ATTR_PARSE_PROCEED;
 
1867 /* Extended Community attribute. */
 
1868 static bgp_attr_parse_ret_t
 
1869 bgp_attr_ext_communities (struct bgp_attr_parser_args *args)
 
1871   struct peer *const peer = args->peer;  
 
1872   struct attr *const attr = args->attr;  
 
1873   const bgp_size_t length = args->length;
 
1878         attr->extra->ecommunity = NULL;
 
1879       /* Empty extcomm doesn't seem to be invalid per se */
 
1880       return BGP_ATTR_PARSE_PROCEED;
 
1883   (bgp_attr_extra_get (attr))->ecommunity =
 
1884     ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
 
1885   /* XXX: fix ecommunity_parse to use stream API */
 
1886   stream_forward_getp (peer->ibuf, length);
 
1888   if (attr->extra && !attr->extra->ecommunity)
 
1889     return bgp_attr_malformed (args,
 
1890                                BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
 
1893   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
 
1895   return BGP_ATTR_PARSE_PROCEED;
 
1898 /* Parse Tunnel Encap attribute in an UPDATE */
 
1902   struct peer   *peer,  /* IN */
 
1903   bgp_size_t    length, /* IN: attr's length field */
 
1904   struct attr   *attr,  /* IN: caller already allocated */
 
1905   u_char        flag,   /* IN: attr's flags field */
 
1909   struct attr_extra             *attre = NULL;
 
1910   struct bgp_attr_encap_subtlv  *stlv_last = NULL;
 
1911   uint16_t                      tunneltype;
 
1913   total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
 
1915   if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
 
1916        || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL))
 
1918       zlog (peer->log, LOG_ERR,
 
1919             "Tunnel Encap attribute flag isn't optional and transitive %d", flag);
 
1920       bgp_notify_send_with_data (peer,
 
1921                                  BGP_NOTIFY_UPDATE_ERR,
 
1922                                  BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
 
1927   if (BGP_ATTR_ENCAP == type) {
 
1928     /* read outer TLV type and length */
 
1929     uint16_t    tlv_length;
 
1932         zlog (peer->log, LOG_ERR,
 
1933             "Tunnel Encap attribute not long enough to contain outer T,L");
 
1934         bgp_notify_send_with_data(peer,
 
1935                                  BGP_NOTIFY_UPDATE_ERR,
 
1936                                  BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
 
1940     tunneltype = stream_getw (BGP_INPUT (peer));
 
1941     tlv_length = stream_getw (BGP_INPUT (peer));
 
1944     if (tlv_length != length) {
 
1945         zlog (peer->log, LOG_ERR, "%s: tlv_length(%d) != length(%d)",
 
1946             __func__, tlv_length, length);
 
1950   while (length >= 4) {
 
1951     uint16_t    subtype = 0;
 
1952     uint16_t    sublength = 0;
 
1953     struct bgp_attr_encap_subtlv *tlv;
 
1955     if (BGP_ATTR_ENCAP == type) {
 
1956         subtype   = stream_getc (BGP_INPUT (peer));
 
1957         sublength = stream_getc (BGP_INPUT (peer));
 
1961     if (sublength > length) {
 
1962       zlog (peer->log, LOG_ERR,
 
1963             "Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
 
1965       bgp_notify_send_with_data (peer,
 
1966                                  BGP_NOTIFY_UPDATE_ERR,
 
1967                                  BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
 
1972     /* alloc and copy sub-tlv */
 
1973     /* TBD make sure these are freed when attributes are released */
 
1974     tlv = XCALLOC (MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv)-1+sublength);
 
1975     tlv->type = subtype;
 
1976     tlv->length = sublength;
 
1977     stream_get(tlv->value, peer->ibuf, sublength);
 
1978     length -= sublength;
 
1980     /* attach tlv to encap chain */
 
1982         attre = bgp_attr_extra_get(attr);
 
1983         if (BGP_ATTR_ENCAP == type) {
 
1984             for (stlv_last = attre->encap_subtlvs; stlv_last && stlv_last->next;
 
1985                 stlv_last = stlv_last->next);
 
1987                 stlv_last->next = tlv;
 
1989                 attre->encap_subtlvs = tlv;
 
1993         stlv_last->next = tlv;
 
1998   if (attre && (BGP_ATTR_ENCAP == type)) {
 
1999       attre->encap_tunneltype = tunneltype;
 
2003     /* spurious leftover data */
 
2004       zlog (peer->log, LOG_ERR,
 
2005             "Tunnel Encap attribute length is bad: %d leftover octets", length);
 
2006       bgp_notify_send_with_data (peer,
 
2007                                  BGP_NOTIFY_UPDATE_ERR,
 
2008                                  BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
 
2016 /* BGP unknown attribute treatment. */
 
2017 static bgp_attr_parse_ret_t
 
2018 bgp_attr_unknown (struct bgp_attr_parser_args *args)
 
2020   bgp_size_t total = args->total;
 
2021   struct transit *transit;
 
2022   struct attr_extra *attre;
 
2023   struct peer *const peer = args->peer; 
 
2024   struct attr *const attr = args->attr;
 
2025   u_char *const startp = args->startp;
 
2026   const u_char type = args->type;
 
2027   const u_char flag = args->flags;  
 
2028   const bgp_size_t length = args->length;
 
2031   if (BGP_DEBUG (normal, NORMAL))
 
2032   zlog_debug ("%s Unknown attribute is received (type %d, length %d)",
 
2033               peer->host, type, length);
 
2035   if (BGP_DEBUG (events, EVENTS))
 
2036     zlog (peer->log, LOG_DEBUG, 
 
2037           "Unknown attribute type %d length %d is received", type, length);
 
2039   /* Forward read pointer of input stream. */
 
2040   stream_forward_getp (peer->ibuf, length);
 
2042   /* If any of the mandatory well-known attributes are not recognized,
 
2043      then the Error Subcode is set to Unrecognized Well-known
 
2044      Attribute.  The Data field contains the unrecognized attribute
 
2045      (type, length and value). */
 
2046   if (!CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
 
2048       return bgp_attr_malformed (args,
 
2049                                  BGP_NOTIFY_UPDATE_UNREC_ATTR,
 
2053   /* Unrecognized non-transitive optional attributes must be quietly
 
2054      ignored and not passed along to other BGP peers. */
 
2055   if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
 
2056     return BGP_ATTR_PARSE_PROCEED;
 
2058   /* If a path with recognized transitive optional attribute is
 
2059      accepted and passed along to other BGP peers and the Partial bit
 
2060      in the Attribute Flags octet is set to 1 by some previous AS, it
 
2061      is not set back to 0 by the current AS. */
 
2062   SET_FLAG (*startp, BGP_ATTR_FLAG_PARTIAL);
 
2064   /* Store transitive attribute to the end of attr->transit. */
 
2065   if (! ((attre = bgp_attr_extra_get(attr))->transit) )
 
2066       attre->transit = XCALLOC (MTYPE_TRANSIT, sizeof (struct transit));
 
2068   transit = attre->transit;
 
2071     transit->val = XREALLOC (MTYPE_TRANSIT_VAL, transit->val, 
 
2072                              transit->length + total);
 
2074     transit->val = XMALLOC (MTYPE_TRANSIT_VAL, total);
 
2076   memcpy (transit->val + transit->length, startp, total);
 
2077   transit->length += total;
 
2079   return BGP_ATTR_PARSE_PROCEED;
 
2082 /* Well-known attribute check. */
 
2084 bgp_attr_check (struct peer *peer, struct attr *attr)
 
2088   /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an
 
2090   if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag)
 
2091     return BGP_ATTR_PARSE_PROCEED;
 
2093   /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required
 
2094      to carry any other path attributes.", though if MP_REACH_NLRI or NLRI
 
2095      are present, it should.  Check for any other attribute being present
 
2098   if (attr->flag == ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI))
 
2099     return BGP_ATTR_PARSE_PROCEED;
 
2101   if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_ORIGIN)))
 
2102     type = BGP_ATTR_ORIGIN;
 
2104   if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH)))
 
2105     type = BGP_ATTR_AS_PATH;
 
2107   /* RFC 2858 makes Next-Hop optional/ignored, if MP_REACH_NLRI is present and
 
2108    * NLRI is empty. We can't easily check NLRI empty here though.
 
2110   if (!CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))
 
2111       && !CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_MP_REACH_NLRI)))
 
2112     type = BGP_ATTR_NEXT_HOP;
 
2114   if (peer->sort == BGP_PEER_IBGP
 
2115       && ! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
 
2116     type = BGP_ATTR_LOCAL_PREF;
 
2120       zlog (peer->log, LOG_WARNING, 
 
2121             "%s Missing well-known attribute %d / %s",
 
2122             peer->host, type, LOOKUP (attr_str, type));
 
2123       bgp_notify_send_with_data (peer, 
 
2124                                  BGP_NOTIFY_UPDATE_ERR, 
 
2125                                  BGP_NOTIFY_UPDATE_MISS_ATTR,
 
2127       return BGP_ATTR_PARSE_ERROR;
 
2129   return BGP_ATTR_PARSE_PROCEED;
 
2132 /* Read attribute of update packet.  This function is called from
 
2133    bgp_update_receive() in bgp_packet.c.  */
 
2134 bgp_attr_parse_ret_t
 
2135 bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
 
2136                 struct bgp_nlri *mp_update, struct bgp_nlri *mp_withdraw)
 
2142   u_char *startp, *endp;
 
2144   u_char seen[BGP_ATTR_BITMAP_SIZE];
 
2145   /* we need the as4_path only until we have synthesized the as_path with it */
 
2146   /* same goes for as4_aggregator */
 
2147   struct aspath *as4_path = NULL;
 
2148   as_t as4_aggregator = 0;
 
2149   struct in_addr as4_aggregator_addr = { .s_addr = 0 };
 
2151   /* Initialize bitmap. */
 
2152   memset (seen, 0, BGP_ATTR_BITMAP_SIZE);
 
2154   /* End pointer of BGP attribute. */
 
2155   assert (size <= stream_get_size (BGP_INPUT (peer)));
 
2156   assert (size <= stream_get_endp (BGP_INPUT (peer)));
 
2157   endp = BGP_INPUT_PNT (peer) + size;
 
2159   /* Get attributes to the end of attribute length. */
 
2160   while (BGP_INPUT_PNT (peer) < endp)
 
2162       /* Check remaining length check.*/
 
2163       if (endp - BGP_INPUT_PNT (peer) < BGP_ATTR_MIN_LEN)
 
2165           /* XXX warning: long int format, int arg (arg 5) */
 
2166           zlog (peer->log, LOG_WARNING, 
 
2167                 "%s: error BGP attribute length %lu is smaller than min len",
 
2169                 (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
 
2171           bgp_notify_send (peer, 
 
2172                            BGP_NOTIFY_UPDATE_ERR, 
 
2173                            BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
 
2174           return BGP_ATTR_PARSE_ERROR;
 
2177       /* Fetch attribute flag and type. */
 
2178       startp = BGP_INPUT_PNT (peer);
 
2179       /* "The lower-order four bits of the Attribute Flags octet are
 
2180          unused.  They MUST be zero when sent and MUST be ignored when
 
2182       flag = 0xF0 & stream_getc (BGP_INPUT (peer));
 
2183       type = stream_getc (BGP_INPUT (peer));
 
2185       /* Check whether Extended-Length applies and is in bounds */
 
2186       if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN)
 
2187           && ((endp - startp) < (BGP_ATTR_MIN_LEN + 1)))
 
2189           zlog (peer->log, LOG_WARNING, 
 
2190                 "%s: Extended length set, but just %lu bytes of attr header",
 
2192                 (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
 
2194           bgp_notify_send (peer, 
 
2195                            BGP_NOTIFY_UPDATE_ERR, 
 
2196                            BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
 
2197           return BGP_ATTR_PARSE_ERROR;
 
2200       /* Check extended attribue length bit. */
 
2201       if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN))
 
2202         length = stream_getw (BGP_INPUT (peer));
 
2204         length = stream_getc (BGP_INPUT (peer));
 
2206       /* If any attribute appears more than once in the UPDATE
 
2207          message, then the Error Subcode is set to Malformed Attribute
 
2210       if (CHECK_BITMAP (seen, type))
 
2212           zlog (peer->log, LOG_WARNING,
 
2213                 "%s: error BGP attribute type %d appears twice in a message",
 
2216           bgp_notify_send (peer, 
 
2217                            BGP_NOTIFY_UPDATE_ERR, 
 
2218                            BGP_NOTIFY_UPDATE_MAL_ATTR);
 
2219           return BGP_ATTR_PARSE_ERROR;
 
2222       /* Set type to bitmap to check duplicate attribute.  `type' is
 
2223          unsigned char so it never overflow bitmap range. */
 
2225       SET_BITMAP (seen, type);
 
2227       /* Overflow check. */
 
2228       attr_endp =  BGP_INPUT_PNT (peer) + length;
 
2230       if (attr_endp > endp)
 
2232           zlog (peer->log, LOG_WARNING, 
 
2233                 "%s: BGP type %d length %d is too large, attribute total length is %d.  attr_endp is %p.  endp is %p", peer->host, type, length, size, attr_endp, endp);
 
2234           zlog_warn ("%s: BGP type %d length %d is too large, attribute total length is %d.  attr_endp is %p.  endp is %p", peer->host, type, length, size, attr_endp, endp);
 
2235           bgp_notify_send_with_data (peer,
 
2236                                      BGP_NOTIFY_UPDATE_ERR,
 
2237                                      BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
 
2238                                      startp, endp - startp);
 
2239           return BGP_ATTR_PARSE_ERROR;
 
2242         struct bgp_attr_parser_args attr_args = {
 
2249           .total = attr_endp - startp,
 
2253       /* If any recognized attribute has Attribute Flags that conflict
 
2254          with the Attribute Type Code, then the Error Subcode is set to
 
2255          Attribute Flags Error.  The Data field contains the erroneous
 
2256          attribute (type, length and value). */
 
2257       if (bgp_attr_flag_invalid (&attr_args))
 
2259           bgp_attr_parse_ret_t ret;
 
2260           ret = bgp_attr_malformed (&attr_args,
 
2261                                     BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
 
2263           if (ret == BGP_ATTR_PARSE_PROCEED)
 
2268       /* OK check attribute and store it's value. */
 
2271         case BGP_ATTR_ORIGIN:
 
2272           ret = bgp_attr_origin (&attr_args);
 
2274         case BGP_ATTR_AS_PATH:
 
2275           ret = bgp_attr_aspath (&attr_args);
 
2277         case BGP_ATTR_AS4_PATH:
 
2278           ret = bgp_attr_as4_path (&attr_args, &as4_path);
 
2280         case BGP_ATTR_NEXT_HOP: 
 
2281           ret = bgp_attr_nexthop (&attr_args);
 
2283         case BGP_ATTR_MULTI_EXIT_DISC:
 
2284           ret = bgp_attr_med (&attr_args);
 
2286         case BGP_ATTR_LOCAL_PREF:
 
2287           ret = bgp_attr_local_pref (&attr_args);
 
2289         case BGP_ATTR_ATOMIC_AGGREGATE:
 
2290           ret = bgp_attr_atomic (&attr_args);
 
2292         case BGP_ATTR_AGGREGATOR:
 
2293           ret = bgp_attr_aggregator (&attr_args);
 
2295         case BGP_ATTR_AS4_AGGREGATOR:
 
2296           ret = bgp_attr_as4_aggregator (&attr_args,
 
2298                                          &as4_aggregator_addr);
 
2300         case BGP_ATTR_COMMUNITIES:
 
2301           ret = bgp_attr_community (&attr_args);
 
2303         case BGP_ATTR_LARGE_COMMUNITIES:
 
2304           ret = bgp_attr_large_community (&attr_args);
 
2306         case BGP_ATTR_ORIGINATOR_ID:
 
2307           ret = bgp_attr_originator_id (&attr_args);
 
2309         case BGP_ATTR_CLUSTER_LIST:
 
2310           ret = bgp_attr_cluster_list (&attr_args);
 
2312         case BGP_ATTR_MP_REACH_NLRI:
 
2313           ret = bgp_mp_reach_parse (&attr_args, mp_update);
 
2315         case BGP_ATTR_MP_UNREACH_NLRI:
 
2316           ret = bgp_mp_unreach_parse (&attr_args, mp_withdraw);
 
2318         case BGP_ATTR_EXT_COMMUNITIES:
 
2319           ret = bgp_attr_ext_communities (&attr_args);
 
2321         case BGP_ATTR_ENCAP:
 
2322           ret = bgp_attr_encap (type, peer, length, attr, flag, startp);
 
2325           ret = bgp_attr_unknown (&attr_args);
 
2329       if (ret == BGP_ATTR_PARSE_ERROR_NOTIFYPLS)
 
2331           bgp_notify_send (peer, 
 
2332                            BGP_NOTIFY_UPDATE_ERR,
 
2333                            BGP_NOTIFY_UPDATE_MAL_ATTR);
 
2334           ret = BGP_ATTR_PARSE_ERROR;
 
2337       /* If hard error occurred immediately return to the caller. */
 
2338       if (ret == BGP_ATTR_PARSE_ERROR)
 
2340           zlog (peer->log, LOG_WARNING,
 
2341                 "%s: Attribute %s, parse error", 
 
2343                 LOOKUP (attr_str, type));
 
2345             aspath_unintern (&as4_path);
 
2348       if (ret == BGP_ATTR_PARSE_WITHDRAW)
 
2351           zlog (peer->log, LOG_WARNING,
 
2352                 "%s: Attribute %s, parse error - treating as withdrawal",
 
2354                 LOOKUP (attr_str, type));
 
2356             aspath_unintern (&as4_path);
 
2360       /* Check the fetched length. */
 
2361       if (BGP_INPUT_PNT (peer) != attr_endp)
 
2363           zlog (peer->log, LOG_WARNING, 
 
2364                 "%s: BGP attribute %s, fetch error", 
 
2365                 peer->host, LOOKUP (attr_str, type));
 
2366           bgp_notify_send (peer, 
 
2367                            BGP_NOTIFY_UPDATE_ERR, 
 
2368                            BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
 
2370             aspath_unintern (&as4_path);
 
2371           return BGP_ATTR_PARSE_ERROR;
 
2374   /* Check final read pointer is same as end pointer. */
 
2375   if (BGP_INPUT_PNT (peer) != endp)
 
2377       zlog (peer->log, LOG_WARNING, 
 
2378             "%s: BGP attribute %s, length mismatch",
 
2379             peer->host, LOOKUP (attr_str, type));
 
2380       bgp_notify_send (peer, 
 
2381                        BGP_NOTIFY_UPDATE_ERR, 
 
2382                        BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
 
2384         aspath_unintern (&as4_path);
 
2385       return BGP_ATTR_PARSE_ERROR;
 
2388   /* Check all mandatory well-known attributes are present */
 
2390     bgp_attr_parse_ret_t ret;
 
2391     if ((ret = bgp_attr_check (peer, attr)) < 0)
 
2394           aspath_unintern (&as4_path);
 
2400    * At this place we can see whether we got AS4_PATH and/or
 
2401    * AS4_AGGREGATOR from a 16Bit peer and act accordingly.
 
2402    * We can not do this before we've read all attributes because
 
2403    * the as4 handling does not say whether AS4_PATH has to be sent
 
2404    * after AS_PATH or not - and when AS4_AGGREGATOR will be send
 
2405    * in relationship to AGGREGATOR.
 
2406    * So, to be defensive, we are not relying on any order and read
 
2407    * all attributes first, including these 32bit ones, and now,
 
2408    * afterwards, we look what and if something is to be done for as4.
 
2410    * It is possible to not have AS_PATH, e.g. GR EoR and sole
 
2413   /* actually... this doesn't ever return failure currently, but
 
2414    * better safe than sorry */
 
2415   if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH))
 
2416       && bgp_attr_munge_as4_attrs (peer, attr, as4_path,
 
2417                                 as4_aggregator, &as4_aggregator_addr))
 
2419       bgp_notify_send (peer, 
 
2420                        BGP_NOTIFY_UPDATE_ERR,
 
2421                        BGP_NOTIFY_UPDATE_MAL_ATTR);
 
2423         aspath_unintern (&as4_path);
 
2424       return BGP_ATTR_PARSE_ERROR;
 
2427   /* At this stage, we have done all fiddling with as4, and the
 
2428    * resulting info is in attr->aggregator resp. attr->aspath
 
2429    * so we can chuck as4_aggregator and as4_path alltogether in
 
2430    * order to save memory
 
2434       aspath_unintern (&as4_path); /* unintern - it is in the hash */
 
2435       /* The flag that we got this is still there, but that does not
 
2440    * The "rest" of the code does nothing with as4_aggregator.
 
2441    * there is no memory attached specifically which is not part
 
2443    * so ignoring just means do nothing.
 
2446    * Finally do the checks on the aspath we did not do yet
 
2447    * because we waited for a potentially synthesized aspath.
 
2449   if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))
 
2451       ret = bgp_attr_aspath_check (peer, attr);
 
2452       if (ret != BGP_ATTR_PARSE_PROCEED)
 
2456   /* Finally intern unknown attribute. */
 
2457   if (attr->extra && attr->extra->transit)
 
2458     attr->extra->transit = transit_intern (attr->extra->transit);
 
2460   return BGP_ATTR_PARSE_PROCEED;
 
2463 int stream_put_prefix (struct stream *, struct prefix *);
 
2466 bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi,
 
2471   /* Set extended bit always to encode the attribute length as 2 bytes */
 
2472   stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
 
2473   stream_putc (s, BGP_ATTR_MP_REACH_NLRI);
 
2474   sizep = stream_get_endp (s);
 
2475   stream_putw (s, 0);   /* Marker: Attribute length. */
 
2477   stream_putw (s, afi);
 
2478   stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
 
2486         case SAFI_MULTICAST:
 
2488           stream_put_ipv4 (s, attr->nexthop.s_addr);
 
2491           stream_putc (s, 12);
 
2492           stream_putl (s, 0);   /* RD = 0, per RFC */
 
2494           stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
 
2498           stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
 
2500         case SAFI_UNICAST:      /* invalid for IPv4 */
 
2509       case SAFI_MULTICAST:
 
2511           struct attr_extra *attre = attr->extra;
 
2513           assert (attr->extra);
 
2514           stream_putc (s, attre->mp_nexthop_len);
 
2515           stream_put (s, &attre->mp_nexthop_global, 16);
 
2516           if (attre->mp_nexthop_len == 32)
 
2517             stream_put (s, &attre->mp_nexthop_local, 16);
 
2522           struct attr_extra *attre = attr->extra;
 
2524           assert (attr->extra);
 
2525           if (attre->mp_nexthop_len == 16) {
 
2526             stream_putc (s, 24);
 
2527             stream_putl (s, 0);   /* RD = 0, per RFC */
 
2529             stream_put (s, &attre->mp_nexthop_global, 16);
 
2530           } else if (attre->mp_nexthop_len == 32) {
 
2531             stream_putc (s, 48);
 
2532             stream_putl (s, 0);   /* RD = 0, per RFC */
 
2534             stream_put (s, &attre->mp_nexthop_global, 16);
 
2535             stream_putl (s, 0);   /* RD = 0, per RFC */
 
2537             stream_put (s, &attre->mp_nexthop_local, 16);
 
2542           assert (attr->extra);
 
2543           stream_putc (s, 16);
 
2544           stream_put (s, &attr->extra->mp_nexthop_global, 16);
 
2560 bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
 
2561                           struct prefix *p, struct prefix_rd *prd,
 
2564   if (safi == SAFI_MPLS_VPN)
 
2566       /* Tag, RD, Prefix write. */
 
2567       stream_putc (s, p->prefixlen + 88);
 
2568       stream_put (s, tag, 3);
 
2569       stream_put (s, prd->val, 8);
 
2570       stream_put (s, &p->u.prefix, PSIZE (p->prefixlen));
 
2573     stream_put_prefix (s, p);
 
2577 bgp_packet_mpattr_prefix_size (afi_t afi, safi_t safi, struct prefix *p)
 
2579   int size = PSIZE (p->prefixlen);
 
2580   if (safi == SAFI_MPLS_VPN)
 
2586  * Encodes the tunnel encapsulation attribute
 
2589 bgp_packet_mpattr_tea(
 
2596     unsigned int                        attrlenfield = 0;
 
2597     unsigned int                        attrhdrlen   = 0;
 
2598     struct bgp_attr_encap_subtlv        *subtlvs;
 
2599     struct bgp_attr_encap_subtlv        *st;
 
2600     const char                          *attrname;
 
2602     if (!attr || !attr->extra)
 
2606         case BGP_ATTR_ENCAP:
 
2607             attrname = "Tunnel Encap";
 
2608             subtlvs = attr->extra->encap_subtlvs;
 
2611              * The tunnel encap attr has an "outer" tlv.
 
2613              * L = total length of subtlvs,
 
2614              * V = concatenated subtlvs.
 
2616             attrlenfield = 2 + 2;       /* T + L */
 
2617             attrhdrlen   = 1 + 1;       /* subTLV T + L */
 
2625     /* if no tlvs, don't make attr */
 
2626     if (subtlvs == NULL)
 
2629     /* compute attr length */
 
2630     for (st = subtlvs; st; st = st->next) {
 
2631         attrlenfield += (attrhdrlen + st->length);
 
2634     if (attrlenfield > 0xffff) {
 
2635         zlog (peer->log, LOG_ERR,
 
2636             "%s attribute is too long (length=%d), can't send it",
 
2642     if (attrlenfield > 0xff) {
 
2643         /* 2-octet length field */
 
2645             BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
 
2646         stream_putc (s, attrtype);
 
2647         stream_putw (s, attrlenfield & 0xffff);
 
2649         /* 1-octet length field */
 
2650         stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL);
 
2651         stream_putc (s, attrtype);
 
2652         stream_putc (s, attrlenfield & 0xff);
 
2655     if (attrtype == BGP_ATTR_ENCAP) {
 
2656         /* write outer T+L */
 
2657         stream_putw(s, attr->extra->encap_tunneltype);
 
2658         stream_putw(s, attrlenfield - 4);
 
2661     /* write each sub-tlv */
 
2662     for (st = subtlvs; st; st = st->next) {
 
2663         if (attrtype == BGP_ATTR_ENCAP) {
 
2664             stream_putc (s, st->type);
 
2665             stream_putc (s, st->length);
 
2667         stream_put (s, st->value, st->length);
 
2672 bgp_packet_mpattr_end (struct stream *s, size_t sizep)
 
2674   /* Set MP attribute length. Don't count the (2) bytes used to encode
 
2676   stream_putw_at (s, sizep, (stream_get_endp (s) - sizep) - 2);
 
2679 /* Make attribute packet. */
 
2681 bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
 
2682                       struct stream *s, struct attr *attr,
 
2683                       struct prefix *p, afi_t afi, safi_t safi,
 
2684                       struct peer *from, struct prefix_rd *prd, u_char *tag)
 
2687   size_t aspath_sizep;
 
2688   struct aspath *aspath;
 
2689   int send_as4_path = 0;
 
2690   int send_as4_aggregator = 0;
 
2691   int use32bit = (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0;
 
2694     bgp = bgp_get_default ();
 
2696   /* Remember current pointer. */
 
2697   cp = stream_get_endp (s);
 
2699   if (p && !(afi == AFI_IP && safi == SAFI_UNICAST))
 
2701       size_t mpattrlen_pos = 0;
 
2702       mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, attr);
 
2703       bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag);
 
2704       bgp_packet_mpattr_end(s, mpattrlen_pos);
 
2707   /* Origin attribute. */
 
2708   stream_putc (s, BGP_ATTR_FLAG_TRANS);
 
2709   stream_putc (s, BGP_ATTR_ORIGIN);
 
2711   stream_putc (s, attr->origin);
 
2713   /* AS path attribute. */
 
2715   /* If remote-peer is EBGP */
 
2716   if (peer->sort == BGP_PEER_EBGP
 
2717       && (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
 
2718           || attr->aspath->segments == NULL)
 
2719       && (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)))
 
2721       aspath = aspath_dup (attr->aspath);
 
2723       if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
 
2725           /* Strip the confed info, and then stuff our path CONFED_ID
 
2727           aspath = aspath_delete_confed_seq (aspath);
 
2728           aspath = aspath_add_seq (aspath, bgp->confed_id);
 
2732           if (peer->change_local_as) {
 
2733             /* If replace-as is specified, we only use the change_local_as when
 
2734                advertising routes. */
 
2735             if( ! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ) {
 
2736               aspath = aspath_add_seq (aspath, peer->local_as);
 
2738             aspath = aspath_add_seq (aspath, peer->change_local_as);
 
2740             aspath = aspath_add_seq (aspath, peer->local_as);
 
2744   else if (peer->sort == BGP_PEER_CONFED)
 
2746       /* A confed member, so we need to do the AS_CONFED_SEQUENCE thing */
 
2747       aspath = aspath_dup (attr->aspath);
 
2748       aspath = aspath_add_confed_seq (aspath, peer->local_as);
 
2751     aspath = attr->aspath;
 
2753   /* If peer is not AS4 capable, then:
 
2754    * - send the created AS_PATH out as AS4_PATH (optional, transitive),
 
2755    *   but ensure that no AS_CONFED_SEQUENCE and AS_CONFED_SET path segment
 
2756    *   types are in it (i.e. exclude them if they are there)
 
2757    *   AND do this only if there is at least one asnum > 65535 in the path!
 
2758    * - send an AS_PATH out, but put 16Bit ASnums in it, not 32bit, and change
 
2759    *   all ASnums > 65535 to BGP_AS_TRANS
 
2762   stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
 
2763   stream_putc (s, BGP_ATTR_AS_PATH);
 
2764   aspath_sizep = stream_get_endp (s);
 
2766   stream_putw_at (s, aspath_sizep, aspath_put (s, aspath, use32bit));
 
2768   /* OLD session may need NEW_AS_PATH sent, if there are 4-byte ASNs 
 
2771   if (!use32bit && aspath_has_as4 (aspath))
 
2772       send_as4_path = 1; /* we'll do this later, at the correct place */
 
2774   /* Nexthop attribute. */
 
2775   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP) && afi == AFI_IP &&
 
2776     safi ==  SAFI_UNICAST)   /* only write NH attr for unicast safi */
 
2778       stream_putc (s, BGP_ATTR_FLAG_TRANS);
 
2779       stream_putc (s, BGP_ATTR_NEXT_HOP);
 
2781       if (safi == SAFI_MPLS_VPN)
 
2783           if (attr->nexthop.s_addr == 0)
 
2784             stream_put_ipv4 (s, peer->nexthop.v4.s_addr);
 
2786             stream_put_ipv4 (s, attr->nexthop.s_addr);
 
2789         stream_put_ipv4 (s, attr->nexthop.s_addr);
 
2792   /* MED attribute. */
 
2793   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
 
2795       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
 
2796       stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC);
 
2798       stream_putl (s, attr->med);
 
2801   /* Local preference. */
 
2802   if (peer->sort == BGP_PEER_IBGP ||
 
2803       peer->sort == BGP_PEER_CONFED)
 
2805       stream_putc (s, BGP_ATTR_FLAG_TRANS);
 
2806       stream_putc (s, BGP_ATTR_LOCAL_PREF);
 
2808       stream_putl (s, attr->local_pref);
 
2811   /* Atomic aggregate. */
 
2812   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))
 
2814       stream_putc (s, BGP_ATTR_FLAG_TRANS);
 
2815       stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE);
 
2820   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR))
 
2822       assert (attr->extra);
 
2824       /* Common to BGP_ATTR_AGGREGATOR, regardless of ASN size */
 
2825       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
 
2826       stream_putc (s, BGP_ATTR_AGGREGATOR);
 
2830           /* AS4 capable peer */
 
2832           stream_putl (s, attr->extra->aggregator_as);
 
2836           /* 2-byte AS peer */
 
2839           /* Is ASN representable in 2-bytes? Or must AS_TRANS be used? */
 
2840           if ( attr->extra->aggregator_as > 65535 )
 
2842               stream_putw (s, BGP_AS_TRANS);
 
2844               /* we have to send AS4_AGGREGATOR, too.
 
2845                * we'll do that later in order to send attributes in ascending
 
2848               send_as4_aggregator = 1;
 
2851             stream_putw (s, (u_int16_t) attr->extra->aggregator_as);
 
2853       stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
 
2856   /* Community attribute. */
 
2857   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) 
 
2858       && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES)))
 
2860       if (attr->community->size * 4 > 255)
 
2862           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
 
2863           stream_putc (s, BGP_ATTR_COMMUNITIES);
 
2864           stream_putw (s, attr->community->size * 4);
 
2868           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
 
2869           stream_putc (s, BGP_ATTR_COMMUNITIES);
 
2870           stream_putc (s, attr->community->size * 4);
 
2872       stream_put (s, attr->community->val, attr->community->size * 4);
 
2876    * Large Community attribute.
 
2879       CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY)
 
2880       && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES)))
 
2882       if (attr->extra->lcommunity->size * 12 > 255)
 
2884           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
 
2885           stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
 
2886           stream_putw (s, attr->extra->lcommunity->size * 12);
 
2890           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
 
2891           stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
 
2892           stream_putc (s, attr->extra->lcommunity->size * 12);
 
2894       stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12);
 
2897   /* Route Reflector. */
 
2898   if (peer->sort == BGP_PEER_IBGP
 
2900       && from->sort == BGP_PEER_IBGP)
 
2902       /* Originator ID. */
 
2903       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
 
2904       stream_putc (s, BGP_ATTR_ORIGINATOR_ID);
 
2907       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
 
2908         stream_put_in_addr (s, &attr->extra->originator_id);
 
2910         stream_put_in_addr (s, &from->remote_id);
 
2913       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
 
2914       stream_putc (s, BGP_ATTR_CLUSTER_LIST);
 
2916       if (attr->extra && attr->extra->cluster)
 
2918           stream_putc (s, attr->extra->cluster->length + 4);
 
2919           /* If this peer configuration's parent BGP has cluster_id. */
 
2920           if (bgp->config & BGP_CONFIG_CLUSTER_ID)
 
2921             stream_put_in_addr (s, &bgp->cluster_id);
 
2923             stream_put_in_addr (s, &bgp->router_id);
 
2924           stream_put (s, attr->extra->cluster->list, 
 
2925                       attr->extra->cluster->length);
 
2930           /* If this peer configuration's parent BGP has cluster_id. */
 
2931           if (bgp->config & BGP_CONFIG_CLUSTER_ID)
 
2932             stream_put_in_addr (s, &bgp->cluster_id);
 
2934             stream_put_in_addr (s, &bgp->router_id);
 
2938   /* Extended Communities attribute. */
 
2939   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY) 
 
2940       && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES)))
 
2942       struct attr_extra *attre = attr->extra;
 
2946       if (peer->sort == BGP_PEER_IBGP
 
2947           || peer->sort == BGP_PEER_CONFED)
 
2949           if (attre->ecommunity->size * 8 > 255)
 
2951               stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
 
2952               stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
 
2953               stream_putw (s, attre->ecommunity->size * 8);
 
2957               stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
 
2958               stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
 
2959               stream_putc (s, attre->ecommunity->size * 8);
 
2961           stream_put (s, attre->ecommunity->val, attre->ecommunity->size * 8);
 
2967           int ecom_tr_size = 0;
 
2970           for (i = 0; i < attre->ecommunity->size; i++)
 
2972               pnt = attre->ecommunity->val + (i * 8);
 
2975               if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))
 
2983               if (ecom_tr_size * 8 > 255)
 
2985                   stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
 
2986                   stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
 
2987                   stream_putw (s, ecom_tr_size * 8);
 
2991                   stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
 
2992                   stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
 
2993                   stream_putc (s, ecom_tr_size * 8);
 
2996               for (i = 0; i < attre->ecommunity->size; i++)
 
2998                   pnt = attre->ecommunity->val + (i * 8);
 
3001                   if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))
 
3004                   stream_put (s, pnt, 8);
 
3010   if ( send_as4_path )
 
3012       /* If the peer is NOT As4 capable, AND */
 
3013       /* there are ASnums > 65535 in path  THEN
 
3014        * give out AS4_PATH */
 
3016       /* Get rid of all AS_CONFED_SEQUENCE and AS_CONFED_SET
 
3018        * Hm, I wonder...  confederation things *should* only be at
 
3019        * the beginning of an aspath, right?  Then we should use
 
3020        * aspath_delete_confed_seq for this, because it is already
 
3022        * Folks, talk to me: what is reasonable here!?
 
3024       aspath = aspath_delete_confed_seq (aspath);
 
3026       stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
 
3027       stream_putc (s, BGP_ATTR_AS4_PATH);
 
3028       aspath_sizep = stream_get_endp (s);
 
3030       stream_putw_at (s, aspath_sizep, aspath_put (s, aspath, 1));
 
3033   if (aspath != attr->aspath)
 
3034     aspath_free (aspath);
 
3036   if ( send_as4_aggregator ) 
 
3038       assert (attr->extra);
 
3040       /* send AS4_AGGREGATOR, at this place */
 
3041       /* this section of code moved here in order to ensure the correct
 
3042        * *ascending* order of attributes
 
3044       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
 
3045       stream_putc (s, BGP_ATTR_AS4_AGGREGATOR);
 
3047       stream_putl (s, attr->extra->aggregator_as);
 
3048       stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
 
3051   if ((afi == AFI_IP || afi == AFI_IP6) &&
 
3052       (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN))
 
3054         /* Tunnel Encap attribute */
 
3055         bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
 
3058   /* Unknown transit attribute. */
 
3059   if (attr->extra && attr->extra->transit)
 
3060     stream_put (s, attr->extra->transit->val, attr->extra->transit->length);
 
3062   /* Return total size of attribute. */
 
3063   return stream_get_endp (s) - cp;
 
3067 bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi)
 
3069   unsigned long attrlen_pnt;
 
3071   /* Set extended bit always to encode the attribute length as 2 bytes */
 
3072   stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
 
3073   stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
 
3075   attrlen_pnt = stream_get_endp (s);
 
3076   stream_putw (s, 0);           /* Length of this attribute. */
 
3078   stream_putw (s, afi);
 
3079   stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
 
3084 bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
 
3085                              afi_t afi, safi_t safi, struct prefix_rd *prd,
 
3088   bgp_packet_mpattr_prefix (s, afi, safi, p, prd, tag);
 
3092 bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt)
 
3094   bgp_packet_mpattr_end (s, attrlen_pnt);
 
3097 /* Initialization of attribute. */
 
3099 bgp_attr_init (void)
 
3111 bgp_attr_finish (void)
 
3115   community_finish ();
 
3116   ecommunity_finish ();
 
3117   lcommunity_finish ();
 
3122 /* Make attribute packet. */
 
3124 bgp_dump_routes_attr (struct stream *s, struct attr *attr, 
 
3125                       struct prefix *prefix)
 
3130   struct aspath *aspath;
 
3132   /* Remember current pointer. */
 
3133   cp = stream_get_endp (s);
 
3135   /* Place holder of length. */
 
3138   /* Origin attribute. */
 
3139   stream_putc (s, BGP_ATTR_FLAG_TRANS);
 
3140   stream_putc (s, BGP_ATTR_ORIGIN);
 
3142   stream_putc (s, attr->origin);
 
3144   aspath = attr->aspath;
 
3146   stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
 
3147   stream_putc (s, BGP_ATTR_AS_PATH);
 
3148   aspath_lenp = stream_get_endp (s);
 
3151   stream_putw_at (s, aspath_lenp, aspath_put (s, aspath, 1));
 
3153   /* Nexthop attribute. */
 
3154   /* If it's an IPv6 prefix, don't dump the IPv4 nexthop to save space */
 
3156      && prefix->family != AF_INET6
 
3159       stream_putc (s, BGP_ATTR_FLAG_TRANS);
 
3160       stream_putc (s, BGP_ATTR_NEXT_HOP);
 
3162       stream_put_ipv4 (s, attr->nexthop.s_addr);
 
3165   /* MED attribute. */
 
3166   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
 
3168       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
 
3169       stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC);
 
3171       stream_putl (s, attr->med);
 
3174   /* Local preference. */
 
3175   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
 
3177       stream_putc (s, BGP_ATTR_FLAG_TRANS);
 
3178       stream_putc (s, BGP_ATTR_LOCAL_PREF);
 
3180       stream_putl (s, attr->local_pref);
 
3183   /* Atomic aggregate. */
 
3184   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))
 
3186       stream_putc (s, BGP_ATTR_FLAG_TRANS);
 
3187       stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE);
 
3192   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR))
 
3194       assert (attr->extra);
 
3195       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
 
3196       stream_putc (s, BGP_ATTR_AGGREGATOR);
 
3198       stream_putl (s, attr->extra->aggregator_as);
 
3199       stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
 
3202   /* Community attribute. */
 
3203   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES))
 
3205       if (attr->community->size * 4 > 255)
 
3207           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
 
3208           stream_putc (s, BGP_ATTR_COMMUNITIES);
 
3209           stream_putw (s, attr->community->size * 4);
 
3213           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
 
3214           stream_putc (s, BGP_ATTR_COMMUNITIES);
 
3215           stream_putc (s, attr->community->size * 4);
 
3217       stream_put (s, attr->community->val, attr->community->size * 4);
 
3220     /* Large Community attribute. */
 
3221   if (attr->extra && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES))
 
3223       if (attr->extra->lcommunity->size * 12 > 255)
 
3225           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
 
3226           stream_putc (s, BGP_ATTR_COMMUNITIES);
 
3227           stream_putw (s, attr->extra->lcommunity->size * 12);
 
3231           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
 
3232           stream_putc (s, BGP_ATTR_COMMUNITIES);
 
3233           stream_putc (s, attr->extra->lcommunity->size * 12);
 
3236       stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12);
 
3239   /* Add a MP_NLRI attribute to dump the IPv6 next hop */
 
3240   if (prefix != NULL && prefix->family == AF_INET6 && attr->extra &&
 
3241      (attr->extra->mp_nexthop_len == 16 || attr->extra->mp_nexthop_len == 32) )
 
3244       struct attr_extra *attre = attr->extra;
 
3246       stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
 
3247       stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
 
3248       sizep = stream_get_endp (s);
 
3251       stream_putc (s, 0);               /* Marker: Attribute length. */
 
3252       stream_putw(s, AFI_IP6);          /* AFI */
 
3253       stream_putc(s, SAFI_UNICAST);     /* SAFI */
 
3256       stream_putc(s, attre->mp_nexthop_len);
 
3257       stream_put(s, &attre->mp_nexthop_global, 16);
 
3258       if (attre->mp_nexthop_len == 32)
 
3259         stream_put(s, &attre->mp_nexthop_local, 16);
 
3265       stream_put_prefix(s, prefix);
 
3267       /* Set MP attribute length. */
 
3268       stream_putc_at (s, sizep, (stream_get_endp (s) - sizep) - 1);
 
3271   /* Return total size of attribute. */
 
3272   len = stream_get_endp (s) - cp - 2;
 
3273   stream_putw_at (s, cp, len);