]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - bgpd/bgp_attr.c
Import Upstream version 1.2.2
[quagga-debian.git] / bgpd / bgp_attr.c
1 /* BGP attributes management routines.
2    Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
3
4 This file is part of GNU Zebra.
5
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING.  If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.  */
20
21 #include <zebra.h>
22
23 #include "linklist.h"
24 #include "prefix.h"
25 #include "memory.h"
26 #include "vector.h"
27 #include "vty.h"
28 #include "stream.h"
29 #include "log.h"
30 #include "hash.h"
31 #include "jhash.h"
32 #include "filter.h"
33
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"
43 #include "table.h"
44 #include "bgp_encap_types.h"
45
46 /* Attribute strings for logging. */
47 static const struct message attr_str [] = 
48 {
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" },
69   { 21,                        ""},
70   { 22,                        ""},
71   { 23,                        ""},
72   { 24,                        ""},
73   { 25,                        ""},
74   { 26,                        ""},
75   { 27,                        ""},
76   { 28,                        ""},
77   { 29,                        ""},
78   { 30,                        ""},
79   { 31,                        ""},
80   { BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY" }
81 };
82 static const int attr_str_max = array_size(attr_str);
83
84 static const struct message attr_flag_str[] =
85 {
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" },
91 };
92
93 static struct hash *cluster_hash;
94
95 static void *
96 cluster_hash_alloc (void *p)
97 {
98   struct cluster_list * val = (struct cluster_list *) p;
99   struct cluster_list *cluster;
100
101   cluster = XMALLOC (MTYPE_CLUSTER, sizeof (struct cluster_list));
102   cluster->length = val->length;
103
104   if (cluster->length)
105     {
106       cluster->list = XMALLOC (MTYPE_CLUSTER_VAL, val->length);
107       memcpy (cluster->list, val->list, val->length);
108     }
109   else
110     cluster->list = NULL;
111
112   cluster->refcnt = 0;
113
114   return cluster;
115 }
116
117 /* Cluster list related functions. */
118 static struct cluster_list *
119 cluster_parse (struct in_addr * pnt, int length)
120 {
121   struct cluster_list tmp;
122   struct cluster_list *cluster;
123
124   tmp.length = length;
125   tmp.list = pnt;
126
127   cluster = hash_get (cluster_hash, &tmp, cluster_hash_alloc);
128   cluster->refcnt++;
129   return cluster;
130 }
131
132 int
133 cluster_loop_check (struct cluster_list *cluster, struct in_addr originator)
134 {
135   int i;
136     
137   for (i = 0; i < cluster->length / 4; i++)
138     if (cluster->list[i].s_addr == originator.s_addr)
139       return 1;
140   return 0;
141 }
142
143 static unsigned int
144 cluster_hash_key_make (void *p)
145 {
146   const struct cluster_list *cluster = p;
147
148   return jhash(cluster->list, cluster->length, 0);
149 }
150
151 static int
152 cluster_hash_cmp (const void *p1, const void *p2)
153 {
154   const struct cluster_list * cluster1 = p1;
155   const struct cluster_list * cluster2 = p2;
156
157   return (cluster1->length == cluster2->length &&
158           memcmp (cluster1->list, cluster2->list, cluster1->length) == 0);
159 }
160
161 static void
162 cluster_free (struct cluster_list *cluster)
163 {
164   if (cluster->list)
165     XFREE (MTYPE_CLUSTER_VAL, cluster->list);
166   XFREE (MTYPE_CLUSTER, cluster);
167 }
168
169 #if 0
170 static struct cluster_list *
171 cluster_dup (struct cluster_list *cluster)
172 {
173   struct cluster_list *new;
174
175   new = XCALLOC (MTYPE_CLUSTER, sizeof (struct cluster_list));
176   new->length = cluster->length;
177
178   if (cluster->length)
179     {
180       new->list = XMALLOC (MTYPE_CLUSTER_VAL, cluster->length);
181       memcpy (new->list, cluster->list, cluster->length);
182     }
183   else
184     new->list = NULL;
185   
186   return new;
187 }
188 #endif
189
190 static struct cluster_list *
191 cluster_intern (struct cluster_list *cluster)
192 {
193   struct cluster_list *find;
194
195   find = hash_get (cluster_hash, cluster, cluster_hash_alloc);
196   find->refcnt++;
197
198   return find;
199 }
200
201 void
202 cluster_unintern (struct cluster_list *cluster)
203 {
204   if (cluster->refcnt)
205     cluster->refcnt--;
206
207   if (cluster->refcnt == 0)
208     {
209       hash_release (cluster_hash, cluster);
210       cluster_free (cluster);
211     }
212 }
213
214 static void
215 cluster_init (void)
216 {
217   cluster_hash = hash_create (cluster_hash_key_make, cluster_hash_cmp);
218 }
219
220 static void
221 cluster_finish (void)
222 {
223   hash_clean (cluster_hash, (void (*)(void *))cluster_free);
224   hash_free (cluster_hash);
225   cluster_hash = NULL;
226 }
227
228 struct bgp_attr_encap_subtlv *
229 encap_tlv_dup(struct bgp_attr_encap_subtlv *orig)
230 {
231     struct bgp_attr_encap_subtlv *new;
232     struct bgp_attr_encap_subtlv *tail;
233     struct bgp_attr_encap_subtlv *p;
234
235     for (p = orig, tail = new = NULL; p; p = p->next) {
236         int size = sizeof(struct bgp_attr_encap_subtlv) - 1 + p->length;
237         if (tail) {
238             tail->next = XCALLOC(MTYPE_ENCAP_TLV, size);
239             tail = tail->next;
240         } else {
241             tail = new = XCALLOC(MTYPE_ENCAP_TLV, size);
242         }
243         assert(tail);
244         memcpy(tail, p, size);
245         tail->next = NULL;
246     }
247
248     return new;
249 }
250
251 static void
252 encap_free(struct bgp_attr_encap_subtlv *p)
253 {
254     struct bgp_attr_encap_subtlv *next;
255     while (p) {
256         next    = p->next;
257         p->next = NULL;
258         XFREE(MTYPE_ENCAP_TLV, p);
259         p       = next;
260     }
261 }
262
263 void
264 bgp_attr_flush_encap(struct attr *attr)
265 {
266     if (!attr || !attr->extra)
267         return;
268
269     if (attr->extra->encap_subtlvs) {
270         encap_free(attr->extra->encap_subtlvs);
271         attr->extra->encap_subtlvs = NULL;
272     }
273 }
274
275 /*
276  * Compare encap sub-tlv chains
277  *
278  *      1 = equivalent
279  *      0 = not equivalent
280  *
281  * This algorithm could be made faster if needed
282  */
283 static int
284 encap_same(struct bgp_attr_encap_subtlv *h1, struct bgp_attr_encap_subtlv *h2)
285 {
286     struct bgp_attr_encap_subtlv *p;
287     struct bgp_attr_encap_subtlv *q;
288
289     if (!h1 && !h2)
290         return 1;
291     if (h1 && !h2)
292         return 0;
293     if (!h1 && h2)
294         return 0;
295     if (h1 == h2)
296         return 1;
297
298     for (p = h1; p; p = p->next) {
299         for (q = h2; q; q = q->next) {
300             if ((p->type == q->type) &&
301                 (p->length == q->length) &&
302                 !memcmp(p->value, q->value, p->length)) {
303
304                 break;
305             }
306         }
307         if (!q)
308             return 0;
309     }
310
311     for (p = h2; p; p = p->next) {
312         for (q = h1; q; q = q->next) {
313             if ((p->type == q->type) &&
314                 (p->length == q->length) &&
315                 !memcmp(p->value, q->value, p->length)) {
316
317                 break;
318             }
319         }
320         if (!q)
321             return 0;
322     }
323
324     return 1;
325 }
326
327 /* Unknown transit attribute. */
328 static struct hash *transit_hash;
329
330 static void
331 transit_free (struct transit *transit)
332 {
333   if (transit->val)
334     XFREE (MTYPE_TRANSIT_VAL, transit->val);
335   XFREE (MTYPE_TRANSIT, transit);
336 }
337
338
339 static void *
340 transit_hash_alloc (void *p)
341 {
342   /* Transit structure is already allocated.  */
343   return p;
344 }
345
346 static struct transit *
347 transit_intern (struct transit *transit)
348 {
349   struct transit *find;
350
351   find = hash_get (transit_hash, transit, transit_hash_alloc);
352   if (find != transit)
353     transit_free (transit);
354   find->refcnt++;
355
356   return find;
357 }
358
359 void
360 transit_unintern (struct transit *transit)
361 {
362   if (transit->refcnt)
363     transit->refcnt--;
364
365   if (transit->refcnt == 0)
366     {
367       hash_release (transit_hash, transit);
368       transit_free (transit);
369     }
370 }
371
372 static unsigned int
373 transit_hash_key_make (void *p)
374 {
375   const struct transit * transit = p;
376
377   return jhash(transit->val, transit->length, 0);
378 }
379
380 static int
381 transit_hash_cmp (const void *p1, const void *p2)
382 {
383   const struct transit * transit1 = p1;
384   const struct transit * transit2 = p2;
385
386   return (transit1->length == transit2->length &&
387           memcmp (transit1->val, transit2->val, transit1->length) == 0);
388 }
389
390 static void
391 transit_init (void)
392 {
393   transit_hash = hash_create (transit_hash_key_make, transit_hash_cmp);
394 }
395
396 static void
397 transit_finish (void)
398 {
399   hash_clean (transit_hash, (void (*)(void *))transit_free);
400   hash_free (transit_hash);
401   transit_hash = NULL;
402 }
403
404 /* Attribute hash routines. */
405 static struct hash *attrhash;
406
407 static struct attr_extra *
408 bgp_attr_extra_new (void)
409 {
410   return XCALLOC (MTYPE_ATTR_EXTRA, sizeof (struct attr_extra));
411 }
412
413 void
414 bgp_attr_extra_free (struct attr *attr)
415 {
416   if (attr->extra)
417     {
418       if (attr->extra->encap_subtlvs) {
419         encap_free(attr->extra->encap_subtlvs);
420         attr->extra->encap_subtlvs = NULL;
421       }
422       XFREE (MTYPE_ATTR_EXTRA, attr->extra);
423       attr->extra = NULL;
424     }
425 }
426
427 struct attr_extra *
428 bgp_attr_extra_get (struct attr *attr)
429 {
430   if (!attr->extra)
431     attr->extra = bgp_attr_extra_new();
432   return attr->extra;
433 }
434
435 /* Shallow copy of an attribute
436  * Though, not so shallow that it doesn't copy the contents
437  * of the attr_extra pointed to by 'extra'
438  */
439 void
440 bgp_attr_dup (struct attr *new, struct attr *orig)
441 {
442   struct attr_extra *extra = new->extra;
443
444   *new = *orig;
445   /* if caller provided attr_extra space, use it in any case.
446    *
447    * This is neccesary even if orig->extra equals NULL, because otherwise
448    * memory may be later allocated on the heap by bgp_attr_extra_get.
449    *
450    * That memory would eventually be leaked, because the caller must not
451    * call bgp_attr_extra_free if he provided attr_extra on the stack.
452    */
453   if (extra)
454     {
455       new->extra = extra;
456       memset(new->extra, 0, sizeof(struct attr_extra));
457       if (orig->extra) {
458         *new->extra = *orig->extra;
459         if (orig->extra->encap_subtlvs) {
460           new->extra->encap_subtlvs = encap_tlv_dup(orig->extra->encap_subtlvs);
461         }
462       }
463     }
464   else if (orig->extra)
465     {
466       new->extra = bgp_attr_extra_new();
467       *new->extra = *orig->extra;
468       if (orig->extra->encap_subtlvs) {
469         new->extra->encap_subtlvs = encap_tlv_dup(orig->extra->encap_subtlvs);
470       }
471     }
472 }
473
474 unsigned long int
475 attr_count (void)
476 {
477   return attrhash->count;
478 }
479
480 unsigned long int
481 attr_unknown_count (void)
482 {
483   return transit_hash->count;
484 }
485
486 unsigned int
487 attrhash_key_make (void *p)
488 {
489   const struct attr *attr = (struct attr *) p;
490   const struct attr_extra *extra = attr->extra;
491   uint32_t key = 0;
492 #define MIX(val)        key = jhash_1word(val, key)
493
494   MIX(attr->origin);
495   MIX(attr->nexthop.s_addr);
496   MIX(attr->med);
497   MIX(attr->local_pref);
498
499   key += attr->origin;
500   key += attr->nexthop.s_addr;
501   key += attr->med;
502   key += attr->local_pref;
503   
504   if (extra)
505     {
506       MIX(extra->aggregator_as);
507       MIX(extra->aggregator_addr.s_addr);
508       MIX(extra->weight);
509       MIX(extra->mp_nexthop_global_in.s_addr);
510       MIX(extra->originator_id.s_addr);
511       MIX(extra->tag);
512     }
513   
514   if (attr->aspath)
515     MIX(aspath_key_make (attr->aspath));
516   if (attr->community)
517     MIX(community_hash_make (attr->community));
518   
519   if (extra)
520     {
521       if (extra->lcommunity)
522         MIX(lcommunity_hash_make (extra->lcommunity));
523       if (extra->ecommunity)
524         MIX(ecommunity_hash_make (extra->ecommunity));
525       if (extra->cluster)
526         MIX(cluster_hash_key_make (extra->cluster));
527       if (extra->transit)
528         MIX(transit_hash_key_make (extra->transit));
529
530       MIX(extra->mp_nexthop_len);
531       key = jhash(extra->mp_nexthop_global.s6_addr, 16, key);
532       key = jhash(extra->mp_nexthop_local.s6_addr, 16, key);
533     }
534
535   return key;
536 }
537
538 int
539 attrhash_cmp (const void *p1, const void *p2)
540 {
541   const struct attr * attr1 = p1;
542   const struct attr * attr2 = p2;
543
544   if (attr1->flag == attr2->flag
545       && attr1->origin == attr2->origin
546       && attr1->nexthop.s_addr == attr2->nexthop.s_addr
547       && attr1->aspath == attr2->aspath
548       && attr1->community == attr2->community
549       && attr1->med == attr2->med
550       && attr1->local_pref == attr2->local_pref)
551     {
552       const struct attr_extra *ae1 = attr1->extra;
553       const struct attr_extra *ae2 = attr2->extra;
554       
555       if (ae1 && ae2
556           && ae1->aggregator_as == ae2->aggregator_as
557           && ae1->aggregator_addr.s_addr == ae2->aggregator_addr.s_addr
558           && ae1->weight == ae2->weight
559           && ae1->tag == ae2->tag
560           && ae1->mp_nexthop_len == ae2->mp_nexthop_len
561           && IPV6_ADDR_SAME (&ae1->mp_nexthop_global, &ae2->mp_nexthop_global)
562           && IPV6_ADDR_SAME (&ae1->mp_nexthop_local, &ae2->mp_nexthop_local)
563           && IPV4_ADDR_SAME (&ae1->mp_nexthop_global_in, &ae2->mp_nexthop_global_in)
564           && ae1->ecommunity == ae2->ecommunity
565           && ae1->lcommunity == ae2->lcommunity
566           && ae1->cluster == ae2->cluster
567           && ae1->transit == ae2->transit
568           && (ae1->encap_tunneltype == ae2->encap_tunneltype)
569           && encap_same(ae1->encap_subtlvs, ae2->encap_subtlvs)
570           && IPV4_ADDR_SAME (&ae1->originator_id, &ae2->originator_id))
571         return 1;
572       else if (ae1 || ae2)
573         return 0;
574       /* neither attribute has extra attributes, so they're same */
575       return 1;
576     }
577   else
578     return 0;
579 }
580
581 static void
582 attrhash_init (void)
583 {
584   attrhash = hash_create (attrhash_key_make, attrhash_cmp);
585 }
586
587 /*
588  * special for hash_clean below
589  */
590 static void
591 attr_vfree (void *attr)
592 {
593   bgp_attr_extra_free ((struct attr *)attr);
594   XFREE (MTYPE_ATTR, attr);
595 }
596
597 static void
598 attrhash_finish (void)
599 {
600   hash_clean(attrhash, attr_vfree);
601   hash_free (attrhash);
602   attrhash = NULL;
603 }
604
605 static void
606 attr_show_all_iterator (struct hash_backet *backet, struct vty *vty)
607 {
608   struct attr *attr = backet->data;
609
610   vty_out (vty, "attr[%ld] nexthop %s%s", attr->refcnt, 
611            inet_ntoa (attr->nexthop), VTY_NEWLINE);
612 }
613
614 void
615 attr_show_all (struct vty *vty)
616 {
617   hash_iterate (attrhash, 
618                 (void (*)(struct hash_backet *, void *))
619                 attr_show_all_iterator,
620                 vty);
621 }
622
623 static void *
624 bgp_attr_hash_alloc (void *p)
625 {
626   struct attr * val = (struct attr *) p;
627   struct attr *attr;
628
629   attr = XMALLOC (MTYPE_ATTR, sizeof (struct attr));
630   *attr = *val;
631   if (val->extra)
632     {
633       attr->extra = bgp_attr_extra_new ();
634       *attr->extra = *val->extra;
635
636       if (attr->extra->encap_subtlvs) {
637         attr->extra->encap_subtlvs = encap_tlv_dup(attr->extra->encap_subtlvs);
638       }
639     }
640   attr->refcnt = 0;
641   return attr;
642 }
643
644 /* Internet argument attribute. */
645 struct attr *
646 bgp_attr_intern (struct attr *attr)
647 {
648   struct attr *find;
649
650   /* Intern referenced strucutre. */
651   if (attr->aspath)
652     {
653       if (! attr->aspath->refcnt)
654         attr->aspath = aspath_intern (attr->aspath);
655       else
656         attr->aspath->refcnt++;
657     }
658   if (attr->community)
659     {
660       if (! attr->community->refcnt)
661         attr->community = community_intern (attr->community);
662       else
663         attr->community->refcnt++;
664     }
665   if (attr->extra)
666     {
667       struct attr_extra *attre = attr->extra;
668       
669       if (attre->ecommunity)
670         {
671           if (! attre->ecommunity->refcnt)
672             attre->ecommunity = ecommunity_intern (attre->ecommunity);
673           else
674             attre->ecommunity->refcnt++;
675           
676         }
677       if (attre->lcommunity)
678         {
679           if (! attre->lcommunity->refcnt)
680             attre->lcommunity = lcommunity_intern (attre->lcommunity);
681           else
682             attre->lcommunity->refcnt++;
683         }
684       if (attre->cluster)
685         {
686           if (! attre->cluster->refcnt)
687             attre->cluster = cluster_intern (attre->cluster);
688           else
689             attre->cluster->refcnt++;
690         }
691       if (attre->transit)
692         {
693           if (! attre->transit->refcnt)
694             attre->transit = transit_intern (attre->transit);
695           else
696             attre->transit->refcnt++;
697         }
698     }
699   
700   find = (struct attr *) hash_get (attrhash, attr, bgp_attr_hash_alloc);
701   find->refcnt++;
702   
703   return find;
704 }
705
706
707 /* Make network statement's attribute. */
708 struct attr *
709 bgp_attr_default_set (struct attr *attr, u_char origin)
710 {
711   memset (attr, 0, sizeof (struct attr));
712   bgp_attr_extra_get (attr);
713   
714   attr->origin = origin;
715   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);
716   attr->aspath = aspath_empty ();
717   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
718   attr->extra->weight = BGP_ATTR_DEFAULT_WEIGHT;
719   attr->extra->tag = 0;
720   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
721   attr->extra->mp_nexthop_len = IPV6_MAX_BYTELEN;
722
723   return attr;
724 }
725
726
727 /* Make network statement's attribute. */
728 struct attr *
729 bgp_attr_default_intern (u_char origin)
730 {
731   struct attr attr;
732   struct attr *new;
733
734   memset (&attr, 0, sizeof (struct attr));
735   bgp_attr_extra_get (&attr);
736
737   bgp_attr_default_set(&attr, origin);
738
739   new = bgp_attr_intern (&attr);
740   bgp_attr_extra_free (&attr);
741   
742   aspath_unintern (&new->aspath);
743   return new;
744 }
745
746 /* Create the attributes for an aggregate */
747 struct attr *
748 bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin,
749                            struct aspath *aspath,
750                            struct community *community, int as_set,
751                            u_char atomic_aggregate)
752 {
753   struct attr attr;
754   struct attr *new;
755   struct attr_extra attre;
756
757   memset (&attr, 0, sizeof (struct attr));
758   memset (&attre, 0, sizeof (struct attr_extra));
759   attr.extra = &attre;
760
761   /* Origin attribute. */
762   attr.origin = origin;
763   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);
764
765   /* AS path attribute. */
766   if (aspath)
767     attr.aspath = aspath_intern (aspath);
768   else
769     attr.aspath = aspath_empty ();
770   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
771
772   /* Next hop attribute.  */
773   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
774
775   if (community)
776     {
777       attr.community = community;
778       attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
779     }
780
781   attre.weight = BGP_ATTR_DEFAULT_WEIGHT;
782   attre.mp_nexthop_len = IPV6_MAX_BYTELEN;
783
784   if (! as_set || atomic_aggregate)
785     attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
786   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
787   if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
788     attre.aggregator_as = bgp->confed_id;
789   else
790     attre.aggregator_as = bgp->as;
791   attre.aggregator_addr = bgp->router_id;
792
793   new = bgp_attr_intern (&attr);
794
795   aspath_unintern (&new->aspath);
796   return new;
797 }
798
799 /* Unintern just the sub-components of the attr, but not the attr */
800 void
801 bgp_attr_unintern_sub (struct attr *attr)
802 {
803   /* aspath refcount shoud be decrement. */
804   if (attr->aspath)
805     aspath_unintern (&attr->aspath);
806   UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH));
807   
808   if (attr->community)
809     community_unintern (&attr->community);
810   UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
811   
812   if (attr->extra)
813     {
814       if (attr->extra->ecommunity)
815         ecommunity_unintern (&attr->extra->ecommunity);
816       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES));
817
818       if (attr->extra->lcommunity)
819         lcommunity_unintern (&attr->extra->lcommunity);
820       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
821       
822       if (attr->extra->cluster)
823         cluster_unintern (attr->extra->cluster);
824       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST));
825       
826       if (attr->extra->transit)
827         transit_unintern (attr->extra->transit);
828     }
829 }
830
831 /* Free bgp attribute and aspath. */
832 void
833 bgp_attr_unintern (struct attr **pattr)
834 {
835   struct attr *attr = *pattr;
836   struct attr *ret;
837   struct attr tmp;
838   struct attr_extra tmp_extra;
839   
840   /* Decrement attribute reference. */
841   attr->refcnt--;
842   
843   tmp = *attr;
844   
845   if (attr->extra)
846     {
847       tmp.extra = &tmp_extra;
848       memcpy (tmp.extra, attr->extra, sizeof (struct attr_extra));
849     }
850   
851   /* If reference becomes zero then free attribute object. */
852   if (attr->refcnt == 0)
853     {
854       ret = hash_release (attrhash, attr);
855       assert (ret != NULL);
856       bgp_attr_extra_free (attr);
857       XFREE (MTYPE_ATTR, attr);
858       *pattr = NULL;
859     }
860
861   bgp_attr_unintern_sub (&tmp);
862 }
863
864 void
865 bgp_attr_flush (struct attr *attr)
866 {
867   if (attr->aspath && ! attr->aspath->refcnt)
868     {
869       aspath_free (attr->aspath);
870       attr->aspath = NULL;
871     }
872   if (attr->community && ! attr->community->refcnt)
873     {
874       community_free (attr->community);
875       attr->community = NULL;
876     }
877   if (attr->extra)
878     {
879       struct attr_extra *attre = attr->extra;
880
881       if (attre->ecommunity && ! attre->ecommunity->refcnt)
882         ecommunity_free (&attre->ecommunity);
883       if (attre->lcommunity && ! attre->lcommunity->refcnt)
884         lcommunity_free (&attre->lcommunity);
885       if (attre->cluster && ! attre->cluster->refcnt)
886         {
887           cluster_free (attre->cluster);
888           attre->cluster = NULL;
889         }
890       if (attre->transit && ! attre->transit->refcnt)
891         {
892           transit_free (attre->transit);
893           attre->transit = NULL;
894         }
895       encap_free(attre->encap_subtlvs);
896       attre->encap_subtlvs = NULL;
897     }
898 }
899
900 /* Implement draft-scudder-idr-optional-transitive behaviour and
901  * avoid resetting sessions for malformed attributes which are
902  * are partial/optional and hence where the error likely was not
903  * introduced by the sending neighbour.
904  */
905 static bgp_attr_parse_ret_t
906 bgp_attr_malformed (struct bgp_attr_parser_args *args, u_char subcode,
907                     bgp_size_t length)
908 {
909   struct peer *const peer = args->peer; 
910   const u_int8_t flags = args->flags;
911   /* startp and length must be special-cased, as whether or not to
912    * send the attribute data with the NOTIFY depends on the error,
913    * the caller therefore signals this with the seperate length argument
914    */
915   u_char *notify_datap = (length > 0 ? args->startp : NULL);
916   
917   /* Only relax error handling for eBGP peers */
918   if (peer->sort != BGP_PEER_EBGP)
919     {
920       bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, subcode,
921                                  notify_datap, length);
922       return BGP_ATTR_PARSE_ERROR;
923
924     }
925   
926   /* Adjust the stream getp to the end of the attribute, in case we can
927    * still proceed but the caller hasn't read all the attribute.
928    */
929   stream_set_getp (BGP_INPUT (peer),
930                    (args->startp - STREAM_DATA (BGP_INPUT (peer)))
931                     + args->total);
932   
933   switch (args->type) {
934     /* where an attribute is relatively inconsequential, e.g. it does not
935      * affect route selection, and can be safely ignored, then any such
936      * attributes which are malformed should just be ignored and the route
937      * processed as normal.
938      */
939     case BGP_ATTR_AS4_AGGREGATOR:
940     case BGP_ATTR_AGGREGATOR:
941     case BGP_ATTR_ATOMIC_AGGREGATE:
942       return BGP_ATTR_PARSE_PROCEED;
943     
944     /* Core attributes, particularly ones which may influence route
945      * selection, should always cause session resets
946      */
947     case BGP_ATTR_ORIGIN:
948     case BGP_ATTR_AS_PATH:
949     case BGP_ATTR_NEXT_HOP:
950     case BGP_ATTR_MULTI_EXIT_DISC:
951     case BGP_ATTR_LOCAL_PREF:
952     case BGP_ATTR_COMMUNITIES:
953     case BGP_ATTR_ORIGINATOR_ID:
954     case BGP_ATTR_CLUSTER_LIST:
955     case BGP_ATTR_MP_REACH_NLRI:
956     case BGP_ATTR_MP_UNREACH_NLRI:
957     case BGP_ATTR_EXT_COMMUNITIES:
958       bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, subcode,
959                                  notify_datap, length);
960       return BGP_ATTR_PARSE_ERROR;
961   }
962   
963   /* Partial optional attributes that are malformed should not cause
964    * the whole session to be reset. Instead treat it as a withdrawal
965    * of the routes, if possible.
966    */
967   if (CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS)
968       && CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
969       && CHECK_FLAG (flags, BGP_ATTR_FLAG_PARTIAL))
970     return BGP_ATTR_PARSE_WITHDRAW;
971   
972   /* default to reset */
973   return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
974 }
975
976 /* Find out what is wrong with the path attribute flag bits and log the error.
977    "Flag bits" here stand for Optional, Transitive and Partial, but not for
978    Extended Length. Checking O/T/P bits at once implies, that the attribute
979    being diagnosed is defined by RFC as either a "well-known" or an "optional,
980    non-transitive" attribute. */
981 static void
982 bgp_attr_flags_diagnose (struct bgp_attr_parser_args *args,
983                          u_int8_t desired_flags /* how RFC says it must be */
984 )
985 {
986   u_char seen = 0, i;
987   u_char real_flags = args->flags;
988   const u_int8_t attr_code = args->type;
989   
990   desired_flags &= ~BGP_ATTR_FLAG_EXTLEN;
991   real_flags &= ~BGP_ATTR_FLAG_EXTLEN;
992   for (i = 0; i <= 2; i++) /* O,T,P, but not E */
993     if
994     (
995       CHECK_FLAG (desired_flags, attr_flag_str[i].key) !=
996       CHECK_FLAG (real_flags,    attr_flag_str[i].key)
997     )
998     {
999       zlog (args->peer->log, LOG_ERR, "%s attribute must%s be flagged as \"%s\"",
1000             LOOKUP (attr_str, attr_code),
1001             CHECK_FLAG (desired_flags, attr_flag_str[i].key) ? "" : " not",
1002             attr_flag_str[i].str);
1003       seen = 1;
1004     }
1005   if (!seen)
1006     {
1007       zlog (args->peer->log, LOG_DEBUG,
1008             "Strange, %s called for attr %s, but no problem found with flags"
1009             " (real flags 0x%x, desired 0x%x)",
1010             __func__, LOOKUP (attr_str, attr_code),
1011             real_flags, desired_flags);
1012     }
1013 }
1014
1015 /* Required flags for attributes. EXTLEN will be masked off when testing,
1016  * as will PARTIAL for optional+transitive attributes.
1017  */
1018 const u_int8_t attr_flags_values [] = {
1019   [BGP_ATTR_ORIGIN] =           BGP_ATTR_FLAG_TRANS,
1020   [BGP_ATTR_AS_PATH] =          BGP_ATTR_FLAG_TRANS,
1021   [BGP_ATTR_NEXT_HOP] =         BGP_ATTR_FLAG_TRANS,
1022   [BGP_ATTR_MULTI_EXIT_DISC] =  BGP_ATTR_FLAG_OPTIONAL,
1023   [BGP_ATTR_LOCAL_PREF] =       BGP_ATTR_FLAG_TRANS,
1024   [BGP_ATTR_ATOMIC_AGGREGATE] = BGP_ATTR_FLAG_TRANS,
1025   [BGP_ATTR_AGGREGATOR] =       BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
1026   [BGP_ATTR_COMMUNITIES] =      BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
1027   [BGP_ATTR_ORIGINATOR_ID] =    BGP_ATTR_FLAG_OPTIONAL,
1028   [BGP_ATTR_CLUSTER_LIST] =     BGP_ATTR_FLAG_OPTIONAL,
1029   [BGP_ATTR_MP_REACH_NLRI] =    BGP_ATTR_FLAG_OPTIONAL,
1030   [BGP_ATTR_MP_UNREACH_NLRI] =  BGP_ATTR_FLAG_OPTIONAL,
1031   [BGP_ATTR_EXT_COMMUNITIES] =  BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1032   [BGP_ATTR_AS4_PATH] =         BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1033   [BGP_ATTR_AS4_AGGREGATOR] =   BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1034   [BGP_ATTR_LARGE_COMMUNITIES] = BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
1035 };
1036 static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
1037
1038 static int
1039 bgp_attr_flag_invalid (struct bgp_attr_parser_args *args)
1040 {
1041   u_int8_t mask = BGP_ATTR_FLAG_EXTLEN;
1042   const u_int8_t flags = args->flags;
1043   const u_int8_t attr_code = args->type;
1044   struct peer *const peer = args->peer; 
1045   
1046   /* there may be attributes we don't know about */
1047   if (attr_code > attr_flags_values_max)
1048     return 0;
1049   if (attr_flags_values[attr_code] == 0)
1050     return 0;
1051   
1052   /* RFC4271, "For well-known attributes, the Transitive bit MUST be set to
1053    * 1."
1054    */
1055   if (!CHECK_FLAG (BGP_ATTR_FLAG_OPTIONAL, flags)
1056       && !CHECK_FLAG (BGP_ATTR_FLAG_TRANS, flags))
1057     {
1058       zlog (peer->log, LOG_ERR,
1059             "%s well-known attributes must have transitive flag set (%x)",
1060             LOOKUP (attr_str, attr_code), flags);
1061       return 1;
1062     }
1063   
1064   /* "For well-known attributes and for optional non-transitive attributes,
1065    *  the Partial bit MUST be set to 0." 
1066    */
1067   if (CHECK_FLAG (flags, BGP_ATTR_FLAG_PARTIAL))
1068     {
1069       if (!CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL))
1070         {
1071           zlog (peer->log, LOG_ERR,
1072                 "%s well-known attribute "
1073                 "must NOT have the partial flag set (%x)",
1074                  LOOKUP (attr_str, attr_code), flags);
1075           return 1;
1076         }
1077       if (CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
1078           && !CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS))
1079         {
1080           zlog (peer->log, LOG_ERR,
1081                 "%s optional + transitive attribute "
1082                 "must NOT have the partial flag set (%x)",
1083                  LOOKUP (attr_str, attr_code), flags);
1084           return 1;
1085         }
1086     }
1087   
1088   /* Optional transitive attributes may go through speakers that don't
1089    * reocgnise them and set the Partial bit.
1090    */
1091   if (CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
1092       && CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS))
1093     SET_FLAG (mask, BGP_ATTR_FLAG_PARTIAL);
1094   
1095   if ((flags & ~mask)
1096       == attr_flags_values[attr_code])
1097     return 0;
1098   
1099   bgp_attr_flags_diagnose (args, attr_flags_values[attr_code]);
1100   return 1;
1101 }
1102
1103 /* Get origin attribute of the update message. */
1104 static bgp_attr_parse_ret_t
1105 bgp_attr_origin (struct bgp_attr_parser_args *args)
1106 {
1107   struct peer *const peer = args->peer;
1108   struct attr *const attr = args->attr;
1109   const bgp_size_t length = args->length;
1110   
1111   /* If any recognized attribute has Attribute Length that conflicts
1112      with the expected length (based on the attribute type code), then
1113      the Error Subcode is set to Attribute Length Error.  The Data
1114      field contains the erroneous attribute (type, length and
1115      value). */
1116   if (length != 1)
1117     {
1118       zlog (peer->log, LOG_ERR, "Origin attribute length is not one %d",
1119             length);
1120       return bgp_attr_malformed (args,
1121                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1122                                  args->total);
1123     }
1124
1125   /* Fetch origin attribute. */
1126   attr->origin = stream_getc (BGP_INPUT (peer));
1127
1128   /* If the ORIGIN attribute has an undefined value, then the Error
1129      Subcode is set to Invalid Origin Attribute.  The Data field
1130      contains the unrecognized attribute (type, length and value). */
1131   if ((attr->origin != BGP_ORIGIN_IGP)
1132       && (attr->origin != BGP_ORIGIN_EGP)
1133       && (attr->origin != BGP_ORIGIN_INCOMPLETE))
1134     {
1135       zlog (peer->log, LOG_ERR, "Origin attribute value is invalid %d",
1136               attr->origin);
1137       return bgp_attr_malformed (args,
1138                                  BGP_NOTIFY_UPDATE_INVAL_ORIGIN,
1139                                  args->total);
1140     }
1141
1142   /* Set oring attribute flag. */
1143   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);
1144
1145   return 0;
1146 }
1147
1148 /* Parse AS path information.  This function is wrapper of
1149    aspath_parse. */
1150 static int
1151 bgp_attr_aspath (struct bgp_attr_parser_args *args)
1152 {
1153   struct attr *const attr = args->attr;
1154   struct peer *const peer = args->peer; 
1155   const bgp_size_t length = args->length;
1156   
1157   /*
1158    * peer with AS4 => will get 4Byte ASnums
1159    * otherwise, will get 16 Bit
1160    */
1161   attr->aspath = aspath_parse (peer->ibuf, length, 
1162                                CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV));
1163
1164   /* In case of IBGP, length will be zero. */
1165   if (! attr->aspath)
1166     {
1167       zlog (peer->log, LOG_ERR,
1168             "Malformed AS path from %s, length is %d",
1169             peer->host, length);
1170       return bgp_attr_malformed (args, BGP_NOTIFY_UPDATE_MAL_AS_PATH, 0);
1171     }
1172
1173   /* Set aspath attribute flag. */
1174   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
1175
1176   return BGP_ATTR_PARSE_PROCEED;
1177 }
1178
1179 static bgp_attr_parse_ret_t
1180 bgp_attr_aspath_check (struct peer *const peer, struct attr *const attr)
1181 {
1182   /* These checks were part of bgp_attr_aspath, but with
1183    * as4 we should to check aspath things when
1184    * aspath synthesizing with as4_path has already taken place.
1185    * Otherwise we check ASPATH and use the synthesized thing, and that is
1186    * not right.
1187    * So do the checks later, i.e. here
1188    */
1189   struct bgp *bgp = peer->bgp;
1190   struct aspath *aspath;
1191
1192   /* Confederation sanity check. */
1193   if ((peer->sort == BGP_PEER_CONFED && ! aspath_left_confed_check (attr->aspath)) ||
1194      (peer->sort == BGP_PEER_EBGP && aspath_confed_check (attr->aspath)))
1195     {
1196       zlog (peer->log, LOG_ERR, "Malformed AS path from %s", peer->host);
1197       bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1198                        BGP_NOTIFY_UPDATE_MAL_AS_PATH);
1199       return BGP_ATTR_PARSE_ERROR;
1200     }
1201
1202   /* First AS check for EBGP. */
1203   if (bgp != NULL && bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
1204     {
1205       if (peer->sort == BGP_PEER_EBGP
1206           && ! aspath_firstas_check (attr->aspath, peer->as))
1207         {
1208           zlog (peer->log, LOG_ERR,
1209                 "%s incorrect first AS (must be %u)", peer->host, peer->as);
1210           bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1211                            BGP_NOTIFY_UPDATE_MAL_AS_PATH);
1212           return BGP_ATTR_PARSE_ERROR;
1213         }
1214     }
1215
1216   /* local-as prepend */
1217   if (peer->change_local_as &&
1218       ! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
1219     {
1220       aspath = aspath_dup (attr->aspath);
1221       aspath = aspath_add_seq (aspath, peer->change_local_as);
1222       aspath_unintern (&attr->aspath);
1223       attr->aspath = aspath_intern (aspath);
1224     }
1225
1226   return BGP_ATTR_PARSE_PROCEED;
1227 }
1228
1229 /* Parse AS4 path information.  This function is another wrapper of
1230    aspath_parse. */
1231 static int
1232 bgp_attr_as4_path (struct bgp_attr_parser_args *args, struct aspath **as4_path)
1233 {
1234   struct peer *const peer = args->peer; 
1235   struct attr *const attr = args->attr;
1236   const bgp_size_t length = args->length;
1237   
1238   *as4_path = aspath_parse (peer->ibuf, length, 1);
1239
1240   /* In case of IBGP, length will be zero. */
1241   if (!*as4_path)
1242     {
1243       zlog (peer->log, LOG_ERR,
1244             "Malformed AS4 path from %s, length is %d",
1245             peer->host, length);
1246       return bgp_attr_malformed (args,
1247                                  BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1248                                  0);
1249     }
1250
1251   /* Set aspath attribute flag. */
1252   if (as4_path)
1253     attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
1254
1255   return BGP_ATTR_PARSE_PROCEED;
1256 }
1257
1258 /* Nexthop attribute. */
1259 static bgp_attr_parse_ret_t
1260 bgp_attr_nexthop (struct bgp_attr_parser_args *args)
1261 {
1262   struct peer *const peer = args->peer; 
1263   struct attr *const attr = args->attr;
1264   const bgp_size_t length = args->length;
1265   
1266   in_addr_t nexthop_h, nexthop_n;
1267
1268   /* Check nexthop attribute length. */
1269   if (length != 4)
1270     {
1271       zlog (peer->log, LOG_ERR, "Nexthop attribute length isn't four [%d]",
1272               length);
1273
1274       return bgp_attr_malformed (args,
1275                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1276                                  args->total);
1277     }
1278
1279   /* According to section 6.3 of RFC4271, syntactically incorrect NEXT_HOP
1280      attribute must result in a NOTIFICATION message (this is implemented below).
1281      At the same time, semantically incorrect NEXT_HOP is more likely to be just
1282      logged locally (this is implemented somewhere else). The UPDATE message
1283      gets ignored in any of these cases. */
1284   nexthop_n = stream_get_ipv4 (peer->ibuf);
1285   nexthop_h = ntohl (nexthop_n);
1286   if ((IPV4_NET0 (nexthop_h) || IPV4_NET127 (nexthop_h) || IPV4_CLASS_DE (nexthop_h))
1287       && !BGP_DEBUG (allow_martians, ALLOW_MARTIANS)) /* loopbacks may be used in testing */
1288     {
1289       char buf[INET_ADDRSTRLEN];
1290       inet_ntop (AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN);
1291       zlog (peer->log, LOG_ERR, "Martian nexthop %s", buf);
1292       return bgp_attr_malformed (args,
1293                                  BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP,
1294                                  args->total);
1295     }
1296
1297   attr->nexthop.s_addr = nexthop_n;
1298   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1299
1300   return BGP_ATTR_PARSE_PROCEED;
1301 }
1302
1303 /* MED atrribute. */
1304 static bgp_attr_parse_ret_t
1305 bgp_attr_med (struct bgp_attr_parser_args *args)
1306 {
1307   struct peer *const peer = args->peer; 
1308   struct attr *const attr = args->attr;
1309   const bgp_size_t length = args->length;
1310   
1311   /* Length check. */
1312   if (length != 4)
1313     {
1314       zlog (peer->log, LOG_ERR, 
1315             "MED attribute length isn't four [%d]", length);
1316
1317       return bgp_attr_malformed (args,
1318                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1319                                  args->total);
1320     }
1321
1322   attr->med = stream_getl (peer->ibuf);
1323
1324   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1325
1326   return BGP_ATTR_PARSE_PROCEED;
1327 }
1328
1329 /* Local preference attribute. */
1330 static bgp_attr_parse_ret_t
1331 bgp_attr_local_pref (struct bgp_attr_parser_args *args)
1332 {
1333   struct peer *const peer = args->peer; 
1334   struct attr *const attr = args->attr;
1335   const bgp_size_t length = args->length;
1336   
1337   /* Length check. */
1338   if (length != 4)
1339   {
1340     zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute length isn't 4 [%u]",
1341           length);
1342     return bgp_attr_malformed (args,
1343                                BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1344                                args->total);
1345   }
1346
1347   /* If it is contained in an UPDATE message that is received from an
1348      external peer, then this attribute MUST be ignored by the
1349      receiving speaker. */
1350   if (peer->sort == BGP_PEER_EBGP)
1351     {
1352       stream_forward_getp (peer->ibuf, length);
1353       return BGP_ATTR_PARSE_PROCEED;
1354     }
1355
1356   attr->local_pref = stream_getl (peer->ibuf);
1357
1358   /* Set atomic aggregate flag. */
1359   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1360
1361   return BGP_ATTR_PARSE_PROCEED;
1362 }
1363
1364 /* Atomic aggregate. */
1365 static int
1366 bgp_attr_atomic (struct bgp_attr_parser_args *args)
1367 {
1368   struct peer *const peer = args->peer; 
1369   struct attr *const attr = args->attr;
1370   const bgp_size_t length = args->length;
1371   
1372   /* Length check. */
1373   if (length != 0)
1374     {
1375       zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute length isn't 0 [%u]",
1376             length);
1377       return bgp_attr_malformed (args,
1378                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1379                                  args->total);
1380     }
1381
1382   /* Set atomic aggregate flag. */
1383   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1384
1385   return BGP_ATTR_PARSE_PROCEED;
1386 }
1387
1388 /* Aggregator attribute */
1389 static int
1390 bgp_attr_aggregator (struct bgp_attr_parser_args *args)
1391 {
1392   struct peer *const peer = args->peer; 
1393   struct attr *const attr = args->attr;
1394   const bgp_size_t length = args->length;
1395   
1396   int wantedlen = 6;
1397   struct attr_extra *attre = bgp_attr_extra_get (attr);
1398   
1399   /* peer with AS4 will send 4 Byte AS, peer without will send 2 Byte */
1400   if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV))
1401     wantedlen = 8;
1402   
1403   if (length != wantedlen)
1404     {
1405       zlog (peer->log, LOG_ERR, "AGGREGATOR attribute length isn't %u [%u]",
1406             wantedlen, length);
1407       return bgp_attr_malformed (args,
1408                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1409                                  args->total);
1410     }
1411   
1412   if ( CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV ) )
1413     attre->aggregator_as = stream_getl (peer->ibuf);
1414   else
1415     attre->aggregator_as = stream_getw (peer->ibuf);
1416   attre->aggregator_addr.s_addr = stream_get_ipv4 (peer->ibuf);
1417
1418   /* Set atomic aggregate flag. */
1419   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1420
1421   return BGP_ATTR_PARSE_PROCEED;
1422 }
1423
1424 /* New Aggregator attribute */
1425 static bgp_attr_parse_ret_t
1426 bgp_attr_as4_aggregator (struct bgp_attr_parser_args *args,
1427                          as_t *as4_aggregator_as,
1428                          struct in_addr *as4_aggregator_addr)
1429 {
1430   struct peer *const peer = args->peer; 
1431   struct attr *const attr = args->attr;
1432   const bgp_size_t length = args->length;
1433       
1434   if (length != 8)
1435     {
1436       zlog (peer->log, LOG_ERR, "New Aggregator length is not 8 [%d]",
1437             length);
1438       return bgp_attr_malformed (args,
1439                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1440                                  0);
1441     }
1442   
1443   *as4_aggregator_as = stream_getl (peer->ibuf);
1444   as4_aggregator_addr->s_addr = stream_get_ipv4 (peer->ibuf);
1445
1446   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_AGGREGATOR);
1447
1448   return BGP_ATTR_PARSE_PROCEED;
1449 }
1450
1451 /* Munge Aggregator and New-Aggregator, AS_PATH and NEW_AS_PATH.
1452  */
1453 static bgp_attr_parse_ret_t
1454 bgp_attr_munge_as4_attrs (struct peer *const peer,
1455                           struct attr *const attr,
1456                           struct aspath *as4_path, as_t as4_aggregator,
1457                           struct in_addr *as4_aggregator_addr)
1458 {
1459   int ignore_as4_path = 0;
1460   struct aspath *newpath;
1461   struct attr_extra *attre = attr->extra;
1462   
1463   if (!attr->aspath)
1464     {
1465       /* NULL aspath shouldn't be possible as bgp_attr_parse should have
1466        * checked that all well-known, mandatory attributes were present.
1467        * 
1468        * Can only be a problem with peer itself - hard error
1469        */
1470       return BGP_ATTR_PARSE_ERROR;
1471     }
1472   
1473   if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV))
1474     {
1475       /* peer can do AS4, so we ignore AS4_PATH and AS4_AGGREGATOR
1476        * if given.
1477        * It is worth a warning though, because the peer really
1478        * should not send them
1479        */
1480       if (BGP_DEBUG(as4, AS4))
1481         {
1482           if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))
1483             zlog_debug ("[AS4] %s %s AS4_PATH",
1484                         peer->host, "AS4 capable peer, yet it sent");
1485           
1486           if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR)))
1487             zlog_debug ("[AS4] %s %s AS4_AGGREGATOR",
1488                         peer->host, "AS4 capable peer, yet it sent");
1489         }
1490       
1491       return BGP_ATTR_PARSE_PROCEED;
1492     }
1493   
1494   /* We have a asn16 peer.  First, look for AS4_AGGREGATOR
1495    * because that may override AS4_PATH
1496    */
1497   if (attr->flag & (ATTR_FLAG_BIT (BGP_ATTR_AS4_AGGREGATOR) ) )
1498     {
1499       if (attr->flag & (ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR) ) )
1500         {
1501           assert (attre);
1502           
1503           /* received both.
1504            * if the as_number in aggregator is not AS_TRANS,
1505            *  then AS4_AGGREGATOR and AS4_PATH shall be ignored
1506            *        and the Aggregator shall be taken as 
1507            *        info on the aggregating node, and the AS_PATH
1508            *        shall be taken as the AS_PATH
1509            *  otherwise
1510            *        the Aggregator shall be ignored and the
1511            *        AS4_AGGREGATOR shall be taken as the
1512            *        Aggregating node and the AS_PATH is to be
1513            *        constructed "as in all other cases"
1514            */
1515           if (attre->aggregator_as != BGP_AS_TRANS)
1516             {
1517               /* ignore */
1518               if ( BGP_DEBUG(as4, AS4))
1519                 zlog_debug ("[AS4] %s BGP not AS4 capable peer" 
1520                             " send AGGREGATOR != AS_TRANS and"
1521                             " AS4_AGGREGATOR, so ignore"
1522                             " AS4_AGGREGATOR and AS4_PATH", peer->host);
1523               ignore_as4_path = 1;
1524             }
1525           else
1526             {
1527               /* "New_aggregator shall be taken as aggregator" */
1528               attre->aggregator_as = as4_aggregator;
1529               attre->aggregator_addr.s_addr = as4_aggregator_addr->s_addr;
1530             }
1531         }
1532       else
1533         {
1534           /* We received a AS4_AGGREGATOR but no AGGREGATOR.
1535            * That is bogus - but reading the conditions
1536            * we have to handle AS4_AGGREGATOR as if it were
1537            * AGGREGATOR in that case
1538            */
1539           if ( BGP_DEBUG(as4, AS4))
1540             zlog_debug ("[AS4] %s BGP not AS4 capable peer send"
1541                         " AS4_AGGREGATOR but no AGGREGATOR, will take"
1542                         " it as if AGGREGATOR with AS_TRANS had been there", peer->host);
1543           (attre = bgp_attr_extra_get (attr))->aggregator_as = as4_aggregator;
1544           /* sweep it under the carpet and simulate a "good" AGGREGATOR */
1545           attr->flag |= (ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR));
1546         }
1547     }
1548
1549   /* need to reconcile NEW_AS_PATH and AS_PATH */
1550   if (!ignore_as4_path && (attr->flag & (ATTR_FLAG_BIT( BGP_ATTR_AS4_PATH))))
1551     {
1552       newpath = aspath_reconcile_as4 (attr->aspath, as4_path);
1553       aspath_unintern (&attr->aspath);
1554       attr->aspath = aspath_intern (newpath);
1555     }
1556   return BGP_ATTR_PARSE_PROCEED;
1557 }
1558
1559 /* Community attribute. */
1560 static bgp_attr_parse_ret_t
1561 bgp_attr_community (struct bgp_attr_parser_args *args)
1562 {
1563   struct peer *const peer = args->peer; 
1564   struct attr *const attr = args->attr;  
1565   const bgp_size_t length = args->length;
1566   
1567   if (length == 0)
1568     {
1569       attr->community = NULL;
1570       return BGP_ATTR_PARSE_PROCEED;
1571     }
1572   
1573   attr->community =
1574     community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length);
1575   
1576   /* XXX: fix community_parse to use stream API and remove this */
1577   stream_forward_getp (peer->ibuf, length);
1578
1579   if (!attr->community)
1580     return bgp_attr_malformed (args,
1581                                BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1582                                args->total);
1583   
1584   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1585
1586   return BGP_ATTR_PARSE_PROCEED;
1587 }
1588
1589 /* Originator ID attribute. */
1590 static bgp_attr_parse_ret_t
1591 bgp_attr_originator_id (struct bgp_attr_parser_args *args)
1592 {
1593   struct peer *const peer = args->peer; 
1594   struct attr *const attr = args->attr;
1595   const bgp_size_t length = args->length;
1596   
1597   /* Length check. */
1598   if (length != 4)
1599     {
1600       zlog (peer->log, LOG_ERR, "Bad originator ID length %d", length);
1601
1602       return bgp_attr_malformed (args,
1603                                  BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1604                                  args->total);
1605     }
1606
1607   (bgp_attr_extra_get (attr))->originator_id.s_addr 
1608     = stream_get_ipv4 (peer->ibuf);
1609
1610   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
1611
1612   return BGP_ATTR_PARSE_PROCEED;
1613 }
1614
1615 /* Cluster list attribute. */
1616 static bgp_attr_parse_ret_t
1617 bgp_attr_cluster_list (struct bgp_attr_parser_args *args)
1618 {
1619   struct peer *const peer = args->peer; 
1620   struct attr *const attr = args->attr;
1621   const bgp_size_t length = args->length;
1622   
1623   /* Check length. */
1624   if (length % 4)
1625     {
1626       zlog (peer->log, LOG_ERR, "Bad cluster list length %d", length);
1627
1628       return bgp_attr_malformed (args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1629                                  args->total);
1630     }
1631
1632   (bgp_attr_extra_get (attr))->cluster 
1633     = cluster_parse ((struct in_addr *)stream_pnt (peer->ibuf), length);
1634   
1635   /* XXX: Fix cluster_parse to use stream API and then remove this */
1636   stream_forward_getp (peer->ibuf, length);
1637
1638   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST);
1639
1640   return BGP_ATTR_PARSE_PROCEED;
1641 }
1642
1643 /* Multiprotocol reachability information parse. */
1644 int
1645 bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
1646                     struct bgp_nlri *mp_update)
1647 {
1648   afi_t afi;
1649   safi_t safi;
1650   bgp_size_t nlri_len;
1651   size_t start;
1652   struct stream *s;
1653   struct peer *const peer = args->peer;  
1654   struct attr *const attr = args->attr;
1655   const bgp_size_t length = args->length;
1656   struct attr_extra *attre = bgp_attr_extra_get(attr);
1657   
1658   /* Set end of packet. */
1659   s = BGP_INPUT(peer);
1660   start = stream_get_getp(s);
1661   
1662   /* safe to read statically sized header? */
1663 #define BGP_MP_REACH_MIN_SIZE 5
1664 #define LEN_LEFT        (length - (stream_get_getp(s) - start))
1665   if ((length > STREAM_READABLE(s)) || (length < BGP_MP_REACH_MIN_SIZE))
1666     {
1667       zlog_info ("%s: %s sent invalid length, %lu", 
1668                  __func__, peer->host, (unsigned long)length);
1669       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1670     }
1671   
1672   /* Load AFI, SAFI. */
1673   afi = stream_getw (s);
1674   safi = stream_getc (s);
1675
1676   /* Get nexthop length. */
1677   attre->mp_nexthop_len = stream_getc (s);
1678   
1679   if (LEN_LEFT < attre->mp_nexthop_len)
1680     {
1681       zlog_info ("%s: %s, MP nexthop length, %u, goes past end of attribute", 
1682                  __func__, peer->host, attre->mp_nexthop_len);
1683       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1684     }
1685   
1686   /* Nexthop length check. */
1687   switch (attre->mp_nexthop_len)
1688     {
1689     case 4:
1690       stream_get (&attre->mp_nexthop_global_in, s, 4);
1691       /* Probably needed for RFC 2283 */
1692       if (attr->nexthop.s_addr == 0)
1693         memcpy(&attr->nexthop.s_addr, &attre->mp_nexthop_global_in, 4);
1694       break;
1695     case 12:
1696       stream_getl (s); /* RD high */
1697       stream_getl (s); /* RD low */
1698       stream_get (&attre->mp_nexthop_global_in, s, 4);
1699       break;
1700     case 24:
1701       {
1702         u_int32_t rd_high __attribute__((unused));
1703         u_int32_t rd_low __attribute__((unused));
1704
1705         rd_high = stream_getl (s);
1706         rd_low = stream_getl (s);
1707       }
1708       /* fall through */
1709     case 16:
1710       stream_get (&attre->mp_nexthop_global, s, 16);
1711       break;
1712     case 32:
1713     case 48:
1714       if (attre->mp_nexthop_len == 48) {
1715         u_int32_t rd_high __attribute__((unused));
1716         u_int32_t rd_low __attribute__((unused));
1717
1718         rd_high = stream_getl (s);
1719         rd_low = stream_getl (s);
1720       }
1721       stream_get (&attre->mp_nexthop_global, s, 16);
1722
1723       if (attre->mp_nexthop_len == 48) {
1724         u_int32_t rd_high __attribute__((unused));
1725         u_int32_t rd_low __attribute__((unused));
1726
1727         rd_high = stream_getl (s);
1728         rd_low = stream_getl (s);
1729       }
1730       stream_get (&attre->mp_nexthop_local, s, 16);
1731       if (! IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local))
1732         {
1733           char buf1[INET6_ADDRSTRLEN];
1734           char buf2[INET6_ADDRSTRLEN];
1735
1736           if (BGP_DEBUG (update, UPDATE_IN))
1737             zlog_debug ("%s got two nexthop %s %s but second one is not a link-local nexthop", peer->host,
1738                        inet_ntop (AF_INET6, &attre->mp_nexthop_global,
1739                                   buf1, INET6_ADDRSTRLEN),
1740                        inet_ntop (AF_INET6, &attre->mp_nexthop_local,
1741                                   buf2, INET6_ADDRSTRLEN));
1742
1743           attre->mp_nexthop_len = 16;
1744         }
1745       break;
1746     default:
1747       zlog_info ("%s: (%s) Wrong multiprotocol next hop length: %d", 
1748                  __func__, peer->host, attre->mp_nexthop_len);
1749       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1750     }
1751
1752   if (!LEN_LEFT)
1753     {
1754       zlog_info ("%s: (%s) Failed to read SNPA and NLRI(s)",
1755                  __func__, peer->host);
1756       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1757     }
1758   
1759   {
1760     u_char val; 
1761     if ((val = stream_getc (s)))
1762     zlog_warn ("%s sent non-zero value, %u, for defunct SNPA-length field",
1763                 peer->host, val);
1764   }
1765   
1766   /* must have nrli_len, what is left of the attribute */
1767   nlri_len = LEN_LEFT;
1768   if ((!nlri_len) || (nlri_len > STREAM_READABLE(s)))
1769     {
1770       zlog_info ("%s: (%s) Failed to read NLRI",
1771                  __func__, peer->host);
1772       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1773     }
1774   
1775   mp_update->afi = afi;
1776   mp_update->safi = safi;
1777   mp_update->nlri = stream_pnt (s);
1778   mp_update->length = nlri_len;
1779
1780   stream_forward_getp (s, nlri_len);
1781
1782   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MP_REACH_NLRI);
1783
1784   return BGP_ATTR_PARSE_PROCEED;
1785 #undef LEN_LEFT
1786 }
1787
1788 /* Multiprotocol unreachable parse */
1789 int
1790 bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
1791                       struct bgp_nlri *mp_withdraw)
1792 {
1793   struct stream *s;
1794   afi_t afi;
1795   safi_t safi;
1796   u_int16_t withdraw_len;
1797   struct peer *const peer = args->peer;  
1798   struct attr *const attr = args->attr;
1799   const bgp_size_t length = args->length;
1800
1801   s = peer->ibuf;
1802   
1803 #define BGP_MP_UNREACH_MIN_SIZE 3
1804   if ((length > STREAM_READABLE(s)) || (length <  BGP_MP_UNREACH_MIN_SIZE))
1805     return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1806   
1807   afi = stream_getw (s);
1808   safi = stream_getc (s);
1809   
1810   withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
1811
1812   mp_withdraw->afi = afi;
1813   mp_withdraw->safi = safi;
1814   mp_withdraw->nlri = stream_pnt (s);
1815   mp_withdraw->length = withdraw_len;
1816
1817   stream_forward_getp (s, withdraw_len);
1818
1819   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI);
1820
1821   return BGP_ATTR_PARSE_PROCEED;
1822 }
1823
1824 /* Large Community attribute. */
1825 static bgp_attr_parse_ret_t
1826 bgp_attr_large_community (struct bgp_attr_parser_args *args)
1827 {
1828   struct peer *const peer = args->peer;
1829   struct attr *const attr = args->attr;
1830   const bgp_size_t length = args->length;
1831
1832   if (length == 0)
1833     {
1834       if (attr->extra)
1835         attr->extra->lcommunity = NULL;
1836       /* Empty extcomm doesn't seem to be invalid per se */
1837       return BGP_ATTR_PARSE_PROCEED;
1838     }
1839
1840   (bgp_attr_extra_get (attr))->lcommunity =
1841     lcommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
1842   /* XXX: fix ecommunity_parse to use stream API */
1843   stream_forward_getp (peer->ibuf, length);
1844
1845   if (attr->extra && !attr->extra->lcommunity)
1846     return bgp_attr_malformed (args,
1847                                BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1848                                args->total);
1849
1850   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
1851
1852   return BGP_ATTR_PARSE_PROCEED;
1853 }
1854
1855 /* Extended Community attribute. */
1856 static bgp_attr_parse_ret_t
1857 bgp_attr_ext_communities (struct bgp_attr_parser_args *args)
1858 {
1859   struct peer *const peer = args->peer;  
1860   struct attr *const attr = args->attr;  
1861   const bgp_size_t length = args->length;
1862   
1863   if (length == 0)
1864     {
1865       if (attr->extra)
1866         attr->extra->ecommunity = NULL;
1867       /* Empty extcomm doesn't seem to be invalid per se */
1868       return BGP_ATTR_PARSE_PROCEED;
1869     }
1870
1871   (bgp_attr_extra_get (attr))->ecommunity =
1872     ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
1873   /* XXX: fix ecommunity_parse to use stream API */
1874   stream_forward_getp (peer->ibuf, length);
1875   
1876   if (attr->extra && !attr->extra->ecommunity)
1877     return bgp_attr_malformed (args,
1878                                BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1879                                args->total);
1880   
1881   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1882
1883   return BGP_ATTR_PARSE_PROCEED;
1884 }
1885
1886 /* Parse Tunnel Encap attribute in an UPDATE */
1887 static int
1888 bgp_attr_encap(
1889   uint8_t       type,
1890   struct peer   *peer,  /* IN */
1891   bgp_size_t    length, /* IN: attr's length field */
1892   struct attr   *attr,  /* IN: caller already allocated */
1893   u_char        flag,   /* IN: attr's flags field */
1894   u_char        *startp)
1895 {
1896   bgp_size_t                    total;
1897   struct attr_extra             *attre = NULL;
1898   struct bgp_attr_encap_subtlv  *stlv_last = NULL;
1899   uint16_t                      tunneltype;
1900
1901   total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
1902
1903   if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
1904        || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL))
1905     {
1906       zlog (peer->log, LOG_ERR,
1907             "Tunnel Encap attribute flag isn't optional and transitive %d", flag);
1908       bgp_notify_send_with_data (peer,
1909                                  BGP_NOTIFY_UPDATE_ERR,
1910                                  BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
1911                                  startp, total);
1912       return -1;
1913     }
1914
1915   if (BGP_ATTR_ENCAP == type) {
1916     /* read outer TLV type and length */
1917     uint16_t    tlv_length;
1918
1919     if (length < 4) {
1920         zlog (peer->log, LOG_ERR,
1921             "Tunnel Encap attribute not long enough to contain outer T,L");
1922         bgp_notify_send_with_data(peer,
1923                                  BGP_NOTIFY_UPDATE_ERR,
1924                                  BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1925                                  startp, total);
1926         return -1;
1927     }
1928     tunneltype = stream_getw (BGP_INPUT (peer));
1929     tlv_length = stream_getw (BGP_INPUT (peer));
1930     length -= 4;
1931
1932     if (tlv_length != length) {
1933         zlog (peer->log, LOG_ERR, "%s: tlv_length(%d) != length(%d)",
1934             __func__, tlv_length, length);
1935     }
1936   }
1937
1938   while (length >= 4) {
1939     uint16_t    subtype = 0;
1940     uint16_t    sublength = 0;
1941     struct bgp_attr_encap_subtlv *tlv;
1942
1943     if (BGP_ATTR_ENCAP == type) {
1944         subtype   = stream_getc (BGP_INPUT (peer));
1945         sublength = stream_getc (BGP_INPUT (peer));
1946         length   -= 2;
1947     }
1948
1949     if (sublength > length) {
1950       zlog (peer->log, LOG_ERR,
1951             "Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
1952             sublength, length);
1953       bgp_notify_send_with_data (peer,
1954                                  BGP_NOTIFY_UPDATE_ERR,
1955                                  BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1956                                  startp, total);
1957       return -1;
1958     }
1959
1960     /* alloc and copy sub-tlv */
1961     /* TBD make sure these are freed when attributes are released */
1962     tlv = XCALLOC (MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv)-1+sublength);
1963     tlv->type = subtype;
1964     tlv->length = sublength;
1965     stream_get(tlv->value, peer->ibuf, sublength);
1966     length -= sublength;
1967
1968     /* attach tlv to encap chain */
1969     if (!attre) {
1970         attre = bgp_attr_extra_get(attr);
1971         if (BGP_ATTR_ENCAP == type) {
1972             for (stlv_last = attre->encap_subtlvs; stlv_last && stlv_last->next;
1973                 stlv_last = stlv_last->next);
1974             if (stlv_last) {
1975                 stlv_last->next = tlv;
1976             } else {
1977                 attre->encap_subtlvs = tlv;
1978             }
1979         }
1980     } else {
1981         stlv_last->next = tlv;
1982     }
1983     stlv_last = tlv;
1984   }
1985
1986   if (attre && (BGP_ATTR_ENCAP == type)) {
1987       attre->encap_tunneltype = tunneltype;
1988   }
1989
1990   if (length) {
1991     /* spurious leftover data */
1992       zlog (peer->log, LOG_ERR,
1993             "Tunnel Encap attribute length is bad: %d leftover octets", length);
1994       bgp_notify_send_with_data (peer,
1995                                  BGP_NOTIFY_UPDATE_ERR,
1996                                  BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1997                                  startp, total);
1998       return -1;
1999   }
2000
2001   return 0;
2002 }
2003
2004 /* BGP unknown attribute treatment. */
2005 static bgp_attr_parse_ret_t
2006 bgp_attr_unknown (struct bgp_attr_parser_args *args)
2007 {
2008   bgp_size_t total = args->total;
2009   struct transit *transit;
2010   struct attr_extra *attre;
2011   struct peer *const peer = args->peer; 
2012   struct attr *const attr = args->attr;
2013   u_char *const startp = args->startp;
2014   const u_char type = args->type;
2015   const u_char flag = args->flags;  
2016   const bgp_size_t length = args->length;
2017   
2018
2019   if (BGP_DEBUG (normal, NORMAL))
2020   zlog_debug ("%s Unknown attribute is received (type %d, length %d)",
2021               peer->host, type, length);
2022   
2023   if (BGP_DEBUG (events, EVENTS))
2024     zlog (peer->log, LOG_DEBUG, 
2025           "Unknown attribute type %d length %d is received", type, length);
2026
2027   /* Forward read pointer of input stream. */
2028   stream_forward_getp (peer->ibuf, length);
2029
2030   /* If any of the mandatory well-known attributes are not recognized,
2031      then the Error Subcode is set to Unrecognized Well-known
2032      Attribute.  The Data field contains the unrecognized attribute
2033      (type, length and value). */
2034   if (!CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
2035     {
2036       return bgp_attr_malformed (args,
2037                                  BGP_NOTIFY_UPDATE_UNREC_ATTR,
2038                                  args->total);
2039     }
2040
2041   /* Unrecognized non-transitive optional attributes must be quietly
2042      ignored and not passed along to other BGP peers. */
2043   if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
2044     return BGP_ATTR_PARSE_PROCEED;
2045
2046   /* If a path with recognized transitive optional attribute is
2047      accepted and passed along to other BGP peers and the Partial bit
2048      in the Attribute Flags octet is set to 1 by some previous AS, it
2049      is not set back to 0 by the current AS. */
2050   SET_FLAG (*startp, BGP_ATTR_FLAG_PARTIAL);
2051
2052   /* Store transitive attribute to the end of attr->transit. */
2053   if (! ((attre = bgp_attr_extra_get(attr))->transit) )
2054       attre->transit = XCALLOC (MTYPE_TRANSIT, sizeof (struct transit));
2055
2056   transit = attre->transit;
2057
2058   if (transit->val)
2059     transit->val = XREALLOC (MTYPE_TRANSIT_VAL, transit->val, 
2060                              transit->length + total);
2061   else
2062     transit->val = XMALLOC (MTYPE_TRANSIT_VAL, total);
2063
2064   memcpy (transit->val + transit->length, startp, total);
2065   transit->length += total;
2066
2067   return BGP_ATTR_PARSE_PROCEED;
2068 }
2069
2070 /* Well-known attribute check. */
2071 static int
2072 bgp_attr_check (struct peer *peer, struct attr *attr)
2073 {
2074   u_char type = 0;
2075   
2076   /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an
2077    * empty UPDATE.  */
2078   if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag)
2079     return BGP_ATTR_PARSE_PROCEED;
2080   
2081   /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required
2082      to carry any other path attributes.", though if MP_REACH_NLRI or NLRI
2083      are present, it should.  Check for any other attribute being present
2084      instead.
2085    */
2086   if (attr->flag == ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI))
2087     return BGP_ATTR_PARSE_PROCEED;
2088   
2089   if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_ORIGIN)))
2090     type = BGP_ATTR_ORIGIN;
2091
2092   if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH)))
2093     type = BGP_ATTR_AS_PATH;
2094   
2095   /* RFC 2858 makes Next-Hop optional/ignored, if MP_REACH_NLRI is present and
2096    * NLRI is empty. We can't easily check NLRI empty here though.
2097    */
2098   if (!CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))
2099       && !CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_MP_REACH_NLRI)))
2100     type = BGP_ATTR_NEXT_HOP;
2101   
2102   if (peer->sort == BGP_PEER_IBGP
2103       && ! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
2104     type = BGP_ATTR_LOCAL_PREF;
2105
2106   if (type)
2107     {
2108       zlog (peer->log, LOG_WARNING, 
2109             "%s Missing well-known attribute %d / %s",
2110             peer->host, type, LOOKUP (attr_str, type));
2111       bgp_notify_send_with_data (peer, 
2112                                  BGP_NOTIFY_UPDATE_ERR, 
2113                                  BGP_NOTIFY_UPDATE_MISS_ATTR,
2114                                  &type, 1);
2115       return BGP_ATTR_PARSE_ERROR;
2116     }
2117   return BGP_ATTR_PARSE_PROCEED;
2118 }
2119
2120 /* Read attribute of update packet.  This function is called from
2121    bgp_update_receive() in bgp_packet.c.  */
2122 bgp_attr_parse_ret_t
2123 bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
2124                 struct bgp_nlri *mp_update, struct bgp_nlri *mp_withdraw)
2125 {
2126   int ret;
2127   u_char flag = 0;
2128   u_char type = 0;
2129   bgp_size_t length;
2130   u_char *startp, *endp;
2131   u_char *attr_endp;
2132   u_char seen[BGP_ATTR_BITMAP_SIZE];
2133   /* we need the as4_path only until we have synthesized the as_path with it */
2134   /* same goes for as4_aggregator */
2135   struct aspath *as4_path = NULL;
2136   as_t as4_aggregator = 0;
2137   struct in_addr as4_aggregator_addr = { .s_addr = 0 };
2138
2139   /* Initialize bitmap. */
2140   memset (seen, 0, BGP_ATTR_BITMAP_SIZE);
2141
2142   /* End pointer of BGP attribute. */
2143   endp = BGP_INPUT_PNT (peer) + size;
2144   
2145   /* Get attributes to the end of attribute length. */
2146   while (BGP_INPUT_PNT (peer) < endp)
2147     {
2148       /* Check remaining length check.*/
2149       if (endp - BGP_INPUT_PNT (peer) < BGP_ATTR_MIN_LEN)
2150         {
2151           /* XXX warning: long int format, int arg (arg 5) */
2152           zlog (peer->log, LOG_WARNING, 
2153                 "%s: error BGP attribute length %lu is smaller than min len",
2154                 peer->host,
2155                 (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
2156
2157           bgp_notify_send (peer, 
2158                            BGP_NOTIFY_UPDATE_ERR, 
2159                            BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
2160           return BGP_ATTR_PARSE_ERROR;
2161         }
2162
2163       /* Fetch attribute flag and type. */
2164       startp = BGP_INPUT_PNT (peer);
2165       /* "The lower-order four bits of the Attribute Flags octet are
2166          unused.  They MUST be zero when sent and MUST be ignored when
2167          received." */
2168       flag = 0xF0 & stream_getc (BGP_INPUT (peer));
2169       type = stream_getc (BGP_INPUT (peer));
2170
2171       /* Check whether Extended-Length applies and is in bounds */
2172       if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN)
2173           && ((endp - startp) < (BGP_ATTR_MIN_LEN + 1)))
2174         {
2175           zlog (peer->log, LOG_WARNING, 
2176                 "%s: Extended length set, but just %lu bytes of attr header",
2177                 peer->host,
2178                 (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
2179
2180           bgp_notify_send (peer, 
2181                            BGP_NOTIFY_UPDATE_ERR, 
2182                            BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
2183           return BGP_ATTR_PARSE_ERROR;
2184         }
2185       
2186       /* Check extended attribue length bit. */
2187       if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN))
2188         length = stream_getw (BGP_INPUT (peer));
2189       else
2190         length = stream_getc (BGP_INPUT (peer));
2191       
2192       /* If any attribute appears more than once in the UPDATE
2193          message, then the Error Subcode is set to Malformed Attribute
2194          List. */
2195
2196       if (CHECK_BITMAP (seen, type))
2197         {
2198           zlog (peer->log, LOG_WARNING,
2199                 "%s: error BGP attribute type %d appears twice in a message",
2200                 peer->host, type);
2201
2202           bgp_notify_send (peer, 
2203                            BGP_NOTIFY_UPDATE_ERR, 
2204                            BGP_NOTIFY_UPDATE_MAL_ATTR);
2205           return BGP_ATTR_PARSE_ERROR;
2206         }
2207
2208       /* Set type to bitmap to check duplicate attribute.  `type' is
2209          unsigned char so it never overflow bitmap range. */
2210
2211       SET_BITMAP (seen, type);
2212
2213       /* Overflow check. */
2214       attr_endp =  BGP_INPUT_PNT (peer) + length;
2215
2216       if (attr_endp > endp)
2217         {
2218           zlog (peer->log, LOG_WARNING, 
2219                 "%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);
2220           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);
2221           bgp_notify_send_with_data (peer,
2222                                      BGP_NOTIFY_UPDATE_ERR,
2223                                      BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2224                                      startp, attr_endp - startp);
2225           return BGP_ATTR_PARSE_ERROR;
2226         }
2227         
2228         struct bgp_attr_parser_args attr_args = {
2229           .peer = peer,
2230           .length = length,
2231           .attr = attr,
2232           .type = type,
2233           .flags = flag,
2234           .startp = startp,
2235           .total = attr_endp - startp,
2236         };
2237       
2238         
2239       /* If any recognized attribute has Attribute Flags that conflict
2240          with the Attribute Type Code, then the Error Subcode is set to
2241          Attribute Flags Error.  The Data field contains the erroneous
2242          attribute (type, length and value). */
2243       if (bgp_attr_flag_invalid (&attr_args))
2244         {
2245           bgp_attr_parse_ret_t ret;
2246           ret = bgp_attr_malformed (&attr_args,
2247                                     BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
2248                                     attr_args.total);
2249           if (ret == BGP_ATTR_PARSE_PROCEED)
2250             continue;
2251           return ret;
2252         }
2253
2254       /* OK check attribute and store it's value. */
2255       switch (type)
2256         {
2257         case BGP_ATTR_ORIGIN:
2258           ret = bgp_attr_origin (&attr_args);
2259           break;
2260         case BGP_ATTR_AS_PATH:
2261           ret = bgp_attr_aspath (&attr_args);
2262           break;
2263         case BGP_ATTR_AS4_PATH:
2264           ret = bgp_attr_as4_path (&attr_args, &as4_path);
2265           break;
2266         case BGP_ATTR_NEXT_HOP: 
2267           ret = bgp_attr_nexthop (&attr_args);
2268           break;
2269         case BGP_ATTR_MULTI_EXIT_DISC:
2270           ret = bgp_attr_med (&attr_args);
2271           break;
2272         case BGP_ATTR_LOCAL_PREF:
2273           ret = bgp_attr_local_pref (&attr_args);
2274           break;
2275         case BGP_ATTR_ATOMIC_AGGREGATE:
2276           ret = bgp_attr_atomic (&attr_args);
2277           break;
2278         case BGP_ATTR_AGGREGATOR:
2279           ret = bgp_attr_aggregator (&attr_args);
2280           break;
2281         case BGP_ATTR_AS4_AGGREGATOR:
2282           ret = bgp_attr_as4_aggregator (&attr_args,
2283                                          &as4_aggregator,
2284                                          &as4_aggregator_addr);
2285           break;
2286         case BGP_ATTR_COMMUNITIES:
2287           ret = bgp_attr_community (&attr_args);
2288           break;
2289         case BGP_ATTR_LARGE_COMMUNITIES:
2290           ret = bgp_attr_large_community (&attr_args);
2291           break;
2292         case BGP_ATTR_ORIGINATOR_ID:
2293           ret = bgp_attr_originator_id (&attr_args);
2294           break;
2295         case BGP_ATTR_CLUSTER_LIST:
2296           ret = bgp_attr_cluster_list (&attr_args);
2297           break;
2298         case BGP_ATTR_MP_REACH_NLRI:
2299           ret = bgp_mp_reach_parse (&attr_args, mp_update);
2300           break;
2301         case BGP_ATTR_MP_UNREACH_NLRI:
2302           ret = bgp_mp_unreach_parse (&attr_args, mp_withdraw);
2303           break;
2304         case BGP_ATTR_EXT_COMMUNITIES:
2305           ret = bgp_attr_ext_communities (&attr_args);
2306           break;
2307         case BGP_ATTR_ENCAP:
2308           ret = bgp_attr_encap (type, peer, length, attr, flag, startp);
2309           break;
2310         default:
2311           ret = bgp_attr_unknown (&attr_args);
2312           break;
2313         }
2314       
2315       if (ret == BGP_ATTR_PARSE_ERROR_NOTIFYPLS)
2316         {
2317           bgp_notify_send (peer, 
2318                            BGP_NOTIFY_UPDATE_ERR,
2319                            BGP_NOTIFY_UPDATE_MAL_ATTR);
2320           ret = BGP_ATTR_PARSE_ERROR;
2321         }
2322
2323       /* If hard error occured immediately return to the caller. */
2324       if (ret == BGP_ATTR_PARSE_ERROR)
2325         {
2326           zlog (peer->log, LOG_WARNING,
2327                 "%s: Attribute %s, parse error", 
2328                 peer->host, 
2329                 LOOKUP (attr_str, type));
2330           if (as4_path)
2331             aspath_unintern (&as4_path);
2332           return ret;
2333         }
2334       if (ret == BGP_ATTR_PARSE_WITHDRAW)
2335         {
2336           
2337           zlog (peer->log, LOG_WARNING,
2338                 "%s: Attribute %s, parse error - treating as withdrawal",
2339                 peer->host,
2340                 LOOKUP (attr_str, type));
2341           if (as4_path)
2342             aspath_unintern (&as4_path);
2343           return ret;
2344         }
2345       
2346       /* Check the fetched length. */
2347       if (BGP_INPUT_PNT (peer) != attr_endp)
2348         {
2349           zlog (peer->log, LOG_WARNING, 
2350                 "%s: BGP attribute %s, fetch error", 
2351                 peer->host, LOOKUP (attr_str, type));
2352           bgp_notify_send (peer, 
2353                            BGP_NOTIFY_UPDATE_ERR, 
2354                            BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
2355           if (as4_path)
2356             aspath_unintern (&as4_path);
2357           return BGP_ATTR_PARSE_ERROR;
2358         }
2359     }
2360   /* Check final read pointer is same as end pointer. */
2361   if (BGP_INPUT_PNT (peer) != endp)
2362     {
2363       zlog (peer->log, LOG_WARNING, 
2364             "%s: BGP attribute %s, length mismatch",
2365             peer->host, LOOKUP (attr_str, type));
2366       bgp_notify_send (peer, 
2367                        BGP_NOTIFY_UPDATE_ERR, 
2368                        BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
2369       if (as4_path)
2370         aspath_unintern (&as4_path);
2371       return BGP_ATTR_PARSE_ERROR;
2372     }
2373   
2374   /* Check all mandatory well-known attributes are present */
2375   {
2376     bgp_attr_parse_ret_t ret;
2377     if ((ret = bgp_attr_check (peer, attr)) < 0)
2378       {
2379         if (as4_path)
2380           aspath_unintern (&as4_path);
2381         return ret;
2382       }
2383   }
2384   
2385   /* 
2386    * At this place we can see whether we got AS4_PATH and/or
2387    * AS4_AGGREGATOR from a 16Bit peer and act accordingly.
2388    * We can not do this before we've read all attributes because
2389    * the as4 handling does not say whether AS4_PATH has to be sent
2390    * after AS_PATH or not - and when AS4_AGGREGATOR will be send
2391    * in relationship to AGGREGATOR.
2392    * So, to be defensive, we are not relying on any order and read
2393    * all attributes first, including these 32bit ones, and now,
2394    * afterwards, we look what and if something is to be done for as4.
2395    *
2396    * It is possible to not have AS_PATH, e.g. GR EoR and sole
2397    * MP_UNREACH_NLRI.
2398    */
2399   /* actually... this doesn't ever return failure currently, but
2400    * better safe than sorry */
2401   if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH))
2402       && bgp_attr_munge_as4_attrs (peer, attr, as4_path,
2403                                 as4_aggregator, &as4_aggregator_addr))
2404     {
2405       bgp_notify_send (peer, 
2406                        BGP_NOTIFY_UPDATE_ERR,
2407                        BGP_NOTIFY_UPDATE_MAL_ATTR);
2408       if (as4_path)
2409         aspath_unintern (&as4_path);
2410       return BGP_ATTR_PARSE_ERROR;
2411     }
2412
2413   /* At this stage, we have done all fiddling with as4, and the
2414    * resulting info is in attr->aggregator resp. attr->aspath
2415    * so we can chuck as4_aggregator and as4_path alltogether in
2416    * order to save memory
2417    */
2418   if (as4_path)
2419     {
2420       aspath_unintern (&as4_path); /* unintern - it is in the hash */
2421       /* The flag that we got this is still there, but that does not
2422        * do any trouble
2423        */
2424     }
2425   /*
2426    * The "rest" of the code does nothing with as4_aggregator.
2427    * there is no memory attached specifically which is not part
2428    * of the attr.
2429    * so ignoring just means do nothing.
2430    */
2431   /*
2432    * Finally do the checks on the aspath we did not do yet
2433    * because we waited for a potentially synthesized aspath.
2434    */
2435   if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))
2436     {
2437       ret = bgp_attr_aspath_check (peer, attr);
2438       if (ret != BGP_ATTR_PARSE_PROCEED)
2439         return ret;
2440     }
2441
2442   /* Finally intern unknown attribute. */
2443   if (attr->extra && attr->extra->transit)
2444     attr->extra->transit = transit_intern (attr->extra->transit);
2445
2446   return BGP_ATTR_PARSE_PROCEED;
2447 }
2448
2449 int stream_put_prefix (struct stream *, struct prefix *);
2450
2451 size_t
2452 bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi,
2453                          struct attr *attr)
2454 {
2455   size_t sizep;
2456
2457   /* Set extended bit always to encode the attribute length as 2 bytes */
2458   stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
2459   stream_putc (s, BGP_ATTR_MP_REACH_NLRI);
2460   sizep = stream_get_endp (s);
2461   stream_putw (s, 0);   /* Marker: Attribute length. */
2462
2463   stream_putw (s, afi);
2464   stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
2465
2466   /* Nexthop */
2467   switch (afi)
2468     {
2469     case AFI_IP:
2470       switch (safi)
2471         {
2472         case SAFI_MULTICAST:
2473           stream_putc (s, 4);
2474           stream_put_ipv4 (s, attr->nexthop.s_addr);
2475           break;
2476         case SAFI_MPLS_VPN:
2477           stream_putc (s, 12);
2478           stream_putl (s, 0);   /* RD = 0, per RFC */
2479           stream_putl (s, 0);
2480           stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
2481           break;
2482         case SAFI_ENCAP:
2483           stream_putc (s, 4);
2484           stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
2485           break;
2486         case SAFI_UNICAST:      /* invalid for IPv4 */
2487         default:
2488           break;
2489         }
2490       break;
2491     case AFI_IP6:
2492       switch (safi)
2493       {
2494       case SAFI_UNICAST:
2495       case SAFI_MULTICAST:
2496         {
2497           struct attr_extra *attre = attr->extra;
2498
2499           assert (attr->extra);
2500           stream_putc (s, attre->mp_nexthop_len);
2501           stream_put (s, &attre->mp_nexthop_global, 16);
2502           if (attre->mp_nexthop_len == 32)
2503             stream_put (s, &attre->mp_nexthop_local, 16);
2504         }
2505         break;
2506       case SAFI_MPLS_VPN:
2507         {
2508           struct attr_extra *attre = attr->extra;
2509
2510           assert (attr->extra);
2511           if (attre->mp_nexthop_len == 16) {
2512             stream_putc (s, 24);
2513             stream_putl (s, 0);   /* RD = 0, per RFC */
2514             stream_putl (s, 0);
2515             stream_put (s, &attre->mp_nexthop_global, 16);
2516           } else if (attre->mp_nexthop_len == 32) {
2517             stream_putc (s, 48);
2518             stream_putl (s, 0);   /* RD = 0, per RFC */
2519             stream_putl (s, 0);
2520             stream_put (s, &attre->mp_nexthop_global, 16);
2521             stream_putl (s, 0);   /* RD = 0, per RFC */
2522             stream_putl (s, 0);
2523             stream_put (s, &attre->mp_nexthop_local, 16);
2524           }
2525         }
2526         break;
2527         case SAFI_ENCAP:
2528           assert (attr->extra);
2529           stream_putc (s, 16);
2530           stream_put (s, &attr->extra->mp_nexthop_global, 16);
2531           break;
2532       default:
2533         break;
2534       }
2535       break;
2536     default:
2537       break;
2538     }
2539
2540   /* SNPA */
2541   stream_putc (s, 0);
2542   return sizep;
2543 }
2544
2545 void
2546 bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
2547                           struct prefix *p, struct prefix_rd *prd,
2548                           u_char *tag)
2549 {
2550   if (safi == SAFI_MPLS_VPN)
2551     {
2552       /* Tag, RD, Prefix write. */
2553       stream_putc (s, p->prefixlen + 88);
2554       stream_put (s, tag, 3);
2555       stream_put (s, prd->val, 8);
2556       stream_put (s, &p->u.prefix, PSIZE (p->prefixlen));
2557     }
2558   else
2559     stream_put_prefix (s, p);
2560 }
2561
2562 size_t
2563 bgp_packet_mpattr_prefix_size (afi_t afi, safi_t safi, struct prefix *p)
2564 {
2565   int size = PSIZE (p->prefixlen);
2566   if (safi == SAFI_MPLS_VPN)
2567       size += 88;
2568   return size;
2569 }
2570
2571 /*
2572  * Encodes the tunnel encapsulation attribute
2573  */
2574 static void
2575 bgp_packet_mpattr_tea(
2576     struct bgp          *bgp,
2577     struct peer         *peer,
2578     struct stream       *s,
2579     struct attr         *attr,
2580     uint8_t             attrtype)
2581 {
2582     unsigned int                        attrlenfield = 0;
2583     unsigned int                        attrhdrlen   = 0;
2584     struct bgp_attr_encap_subtlv        *subtlvs;
2585     struct bgp_attr_encap_subtlv        *st;
2586     const char                          *attrname;
2587
2588     if (!attr || !attr->extra)
2589         return;
2590
2591     switch (attrtype) {
2592         case BGP_ATTR_ENCAP:
2593             attrname = "Tunnel Encap";
2594             subtlvs = attr->extra->encap_subtlvs;
2595
2596             /*
2597              * The tunnel encap attr has an "outer" tlv.
2598              * T = tunneltype,
2599              * L = total length of subtlvs,
2600              * V = concatenated subtlvs.
2601              */
2602             attrlenfield = 2 + 2;       /* T + L */
2603             attrhdrlen   = 1 + 1;       /* subTLV T + L */
2604             break;
2605
2606         default:
2607             assert(0);
2608     }
2609
2610
2611     /* if no tlvs, don't make attr */
2612     if (subtlvs == NULL)
2613         return;
2614
2615     /* compute attr length */
2616     for (st = subtlvs; st; st = st->next) {
2617         attrlenfield += (attrhdrlen + st->length);
2618     }
2619
2620     if (attrlenfield > 0xffff) {
2621         zlog (peer->log, LOG_ERR,
2622             "%s attribute is too long (length=%d), can't send it",
2623             attrname,
2624             attrlenfield);
2625         return;
2626     }
2627
2628     if (attrlenfield > 0xff) {
2629         /* 2-octet length field */
2630         stream_putc (s,
2631             BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
2632         stream_putc (s, attrtype);
2633         stream_putw (s, attrlenfield & 0xffff);
2634     } else {
2635         /* 1-octet length field */
2636         stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL);
2637         stream_putc (s, attrtype);
2638         stream_putc (s, attrlenfield & 0xff);
2639     }
2640
2641     if (attrtype == BGP_ATTR_ENCAP) {
2642         /* write outer T+L */
2643         stream_putw(s, attr->extra->encap_tunneltype);
2644         stream_putw(s, attrlenfield - 4);
2645     }
2646
2647     /* write each sub-tlv */
2648     for (st = subtlvs; st; st = st->next) {
2649         if (attrtype == BGP_ATTR_ENCAP) {
2650             stream_putc (s, st->type);
2651             stream_putc (s, st->length);
2652         }
2653         stream_put (s, st->value, st->length);
2654     }
2655 }
2656
2657 void
2658 bgp_packet_mpattr_end (struct stream *s, size_t sizep)
2659 {
2660   /* Set MP attribute length. Don't count the (2) bytes used to encode
2661      the attr length */
2662   stream_putw_at (s, sizep, (stream_get_endp (s) - sizep) - 2);
2663 }
2664
2665 /* Make attribute packet. */
2666 bgp_size_t
2667 bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
2668                       struct stream *s, struct attr *attr,
2669                       struct prefix *p, afi_t afi, safi_t safi,
2670                       struct peer *from, struct prefix_rd *prd, u_char *tag)
2671 {
2672   size_t cp;
2673   size_t aspath_sizep;
2674   struct aspath *aspath;
2675   int send_as4_path = 0;
2676   int send_as4_aggregator = 0;
2677   int use32bit = (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0;
2678
2679   if (! bgp)
2680     bgp = bgp_get_default ();
2681
2682   /* Remember current pointer. */
2683   cp = stream_get_endp (s);
2684
2685   if (p && !(afi == AFI_IP && safi == SAFI_UNICAST))
2686     {
2687       size_t mpattrlen_pos = 0;
2688       mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi, attr);
2689       bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag);
2690       bgp_packet_mpattr_end(s, mpattrlen_pos);
2691     }
2692
2693   /* Origin attribute. */
2694   stream_putc (s, BGP_ATTR_FLAG_TRANS);
2695   stream_putc (s, BGP_ATTR_ORIGIN);
2696   stream_putc (s, 1);
2697   stream_putc (s, attr->origin);
2698
2699   /* AS path attribute. */
2700
2701   /* If remote-peer is EBGP */
2702   if (peer->sort == BGP_PEER_EBGP
2703       && (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
2704           || attr->aspath->segments == NULL)
2705       && (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)))
2706     {    
2707       aspath = aspath_dup (attr->aspath);
2708
2709       if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
2710         {
2711           /* Strip the confed info, and then stuff our path CONFED_ID
2712              on the front */
2713           aspath = aspath_delete_confed_seq (aspath);
2714           aspath = aspath_add_seq (aspath, bgp->confed_id);
2715         }
2716       else
2717         {
2718           if (peer->change_local_as) {
2719             /* If replace-as is specified, we only use the change_local_as when
2720                advertising routes. */
2721             if( ! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ) {
2722               aspath = aspath_add_seq (aspath, peer->local_as);
2723             }
2724             aspath = aspath_add_seq (aspath, peer->change_local_as);
2725           } else {
2726             aspath = aspath_add_seq (aspath, peer->local_as);
2727           }
2728         }
2729     }
2730   else if (peer->sort == BGP_PEER_CONFED)
2731     {
2732       /* A confed member, so we need to do the AS_CONFED_SEQUENCE thing */
2733       aspath = aspath_dup (attr->aspath);
2734       aspath = aspath_add_confed_seq (aspath, peer->local_as);
2735     }
2736   else
2737     aspath = attr->aspath;
2738
2739   /* If peer is not AS4 capable, then:
2740    * - send the created AS_PATH out as AS4_PATH (optional, transitive),
2741    *   but ensure that no AS_CONFED_SEQUENCE and AS_CONFED_SET path segment
2742    *   types are in it (i.e. exclude them if they are there)
2743    *   AND do this only if there is at least one asnum > 65535 in the path!
2744    * - send an AS_PATH out, but put 16Bit ASnums in it, not 32bit, and change
2745    *   all ASnums > 65535 to BGP_AS_TRANS
2746    */
2747
2748   stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
2749   stream_putc (s, BGP_ATTR_AS_PATH);
2750   aspath_sizep = stream_get_endp (s);
2751   stream_putw (s, 0);
2752   stream_putw_at (s, aspath_sizep, aspath_put (s, aspath, use32bit));
2753   
2754   /* OLD session may need NEW_AS_PATH sent, if there are 4-byte ASNs 
2755    * in the path
2756    */
2757   if (!use32bit && aspath_has_as4 (aspath))
2758       send_as4_path = 1; /* we'll do this later, at the correct place */
2759   
2760   /* Nexthop attribute. */
2761   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP) && afi == AFI_IP &&
2762     safi ==  SAFI_UNICAST)   /* only write NH attr for unicast safi */
2763     {
2764       stream_putc (s, BGP_ATTR_FLAG_TRANS);
2765       stream_putc (s, BGP_ATTR_NEXT_HOP);
2766       stream_putc (s, 4);
2767       if (safi == SAFI_MPLS_VPN)
2768         {
2769           if (attr->nexthop.s_addr == 0)
2770             stream_put_ipv4 (s, peer->nexthop.v4.s_addr);
2771           else
2772             stream_put_ipv4 (s, attr->nexthop.s_addr);
2773         }
2774       else
2775         stream_put_ipv4 (s, attr->nexthop.s_addr);
2776     }
2777
2778   /* MED attribute. */
2779   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
2780     {
2781       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
2782       stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC);
2783       stream_putc (s, 4);
2784       stream_putl (s, attr->med);
2785     }
2786
2787   /* Local preference. */
2788   if (peer->sort == BGP_PEER_IBGP ||
2789       peer->sort == BGP_PEER_CONFED)
2790     {
2791       stream_putc (s, BGP_ATTR_FLAG_TRANS);
2792       stream_putc (s, BGP_ATTR_LOCAL_PREF);
2793       stream_putc (s, 4);
2794       stream_putl (s, attr->local_pref);
2795     }
2796
2797   /* Atomic aggregate. */
2798   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))
2799     {
2800       stream_putc (s, BGP_ATTR_FLAG_TRANS);
2801       stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE);
2802       stream_putc (s, 0);
2803     }
2804
2805   /* Aggregator. */
2806   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR))
2807     {
2808       assert (attr->extra);
2809       
2810       /* Common to BGP_ATTR_AGGREGATOR, regardless of ASN size */
2811       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
2812       stream_putc (s, BGP_ATTR_AGGREGATOR);
2813       
2814       if (use32bit)
2815         {
2816           /* AS4 capable peer */
2817           stream_putc (s, 8);
2818           stream_putl (s, attr->extra->aggregator_as);
2819         }
2820       else
2821         {
2822           /* 2-byte AS peer */
2823           stream_putc (s, 6);
2824           
2825           /* Is ASN representable in 2-bytes? Or must AS_TRANS be used? */
2826           if ( attr->extra->aggregator_as > 65535 )
2827             {
2828               stream_putw (s, BGP_AS_TRANS);
2829               
2830               /* we have to send AS4_AGGREGATOR, too.
2831                * we'll do that later in order to send attributes in ascending
2832                * order.
2833                */
2834               send_as4_aggregator = 1;
2835             }
2836           else
2837             stream_putw (s, (u_int16_t) attr->extra->aggregator_as);
2838         }
2839       stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
2840     }
2841
2842   /* Community attribute. */
2843   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) 
2844       && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES)))
2845     {
2846       if (attr->community->size * 4 > 255)
2847         {
2848           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
2849           stream_putc (s, BGP_ATTR_COMMUNITIES);
2850           stream_putw (s, attr->community->size * 4);
2851         }
2852       else
2853         {
2854           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
2855           stream_putc (s, BGP_ATTR_COMMUNITIES);
2856           stream_putc (s, attr->community->size * 4);
2857         }
2858       stream_put (s, attr->community->val, attr->community->size * 4);
2859     }
2860
2861   /*
2862    * Large Community attribute.
2863    */
2864   if (attr->extra &&
2865       CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY)
2866       && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES)))
2867     {
2868       if (attr->extra->lcommunity->size * 12 > 255)
2869         {
2870           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
2871           stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
2872           stream_putw (s, attr->extra->lcommunity->size * 12);
2873         }
2874       else
2875         {
2876           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
2877           stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
2878           stream_putc (s, attr->extra->lcommunity->size * 12);
2879         }
2880       stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12);
2881     }
2882
2883   /* Route Reflector. */
2884   if (peer->sort == BGP_PEER_IBGP
2885       && from
2886       && from->sort == BGP_PEER_IBGP)
2887     {
2888       /* Originator ID. */
2889       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
2890       stream_putc (s, BGP_ATTR_ORIGINATOR_ID);
2891       stream_putc (s, 4);
2892
2893       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
2894         stream_put_in_addr (s, &attr->extra->originator_id);
2895       else 
2896         stream_put_in_addr (s, &from->remote_id);
2897
2898       /* Cluster list. */
2899       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
2900       stream_putc (s, BGP_ATTR_CLUSTER_LIST);
2901       
2902       if (attr->extra && attr->extra->cluster)
2903         {
2904           stream_putc (s, attr->extra->cluster->length + 4);
2905           /* If this peer configuration's parent BGP has cluster_id. */
2906           if (bgp->config & BGP_CONFIG_CLUSTER_ID)
2907             stream_put_in_addr (s, &bgp->cluster_id);
2908           else
2909             stream_put_in_addr (s, &bgp->router_id);
2910           stream_put (s, attr->extra->cluster->list, 
2911                       attr->extra->cluster->length);
2912         }
2913       else
2914         {
2915           stream_putc (s, 4);
2916           /* If this peer configuration's parent BGP has cluster_id. */
2917           if (bgp->config & BGP_CONFIG_CLUSTER_ID)
2918             stream_put_in_addr (s, &bgp->cluster_id);
2919           else
2920             stream_put_in_addr (s, &bgp->router_id);
2921         }
2922     }
2923
2924   /* Extended Communities attribute. */
2925   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY) 
2926       && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES)))
2927     {
2928       struct attr_extra *attre = attr->extra;
2929       
2930       assert (attre);
2931       
2932       if (peer->sort == BGP_PEER_IBGP
2933           || peer->sort == BGP_PEER_CONFED)
2934         {
2935           if (attre->ecommunity->size * 8 > 255)
2936             {
2937               stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
2938               stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
2939               stream_putw (s, attre->ecommunity->size * 8);
2940             }
2941           else
2942             {
2943               stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
2944               stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
2945               stream_putc (s, attre->ecommunity->size * 8);
2946             }
2947           stream_put (s, attre->ecommunity->val, attre->ecommunity->size * 8);
2948         }
2949       else
2950         {
2951           u_int8_t *pnt;
2952           int tbit;
2953           int ecom_tr_size = 0;
2954           int i;
2955
2956           for (i = 0; i < attre->ecommunity->size; i++)
2957             {
2958               pnt = attre->ecommunity->val + (i * 8);
2959               tbit = *pnt;
2960
2961               if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))
2962                 continue;
2963
2964               ecom_tr_size++;
2965             }
2966
2967           if (ecom_tr_size)
2968             {
2969               if (ecom_tr_size * 8 > 255)
2970                 {
2971                   stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
2972                   stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
2973                   stream_putw (s, ecom_tr_size * 8);
2974                 }
2975               else
2976                 {
2977                   stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
2978                   stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
2979                   stream_putc (s, ecom_tr_size * 8);
2980                 }
2981
2982               for (i = 0; i < attre->ecommunity->size; i++)
2983                 {
2984                   pnt = attre->ecommunity->val + (i * 8);
2985                   tbit = *pnt;
2986
2987                   if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))
2988                     continue;
2989
2990                   stream_put (s, pnt, 8);
2991                 }
2992             }
2993         }
2994     }
2995
2996   if ( send_as4_path )
2997     {
2998       /* If the peer is NOT As4 capable, AND */
2999       /* there are ASnums > 65535 in path  THEN
3000        * give out AS4_PATH */
3001
3002       /* Get rid of all AS_CONFED_SEQUENCE and AS_CONFED_SET
3003        * path segments!
3004        * Hm, I wonder...  confederation things *should* only be at
3005        * the beginning of an aspath, right?  Then we should use
3006        * aspath_delete_confed_seq for this, because it is already
3007        * there! (JK) 
3008        * Folks, talk to me: what is reasonable here!?
3009        */
3010       aspath = aspath_delete_confed_seq (aspath);
3011
3012       stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
3013       stream_putc (s, BGP_ATTR_AS4_PATH);
3014       aspath_sizep = stream_get_endp (s);
3015       stream_putw (s, 0);
3016       stream_putw_at (s, aspath_sizep, aspath_put (s, aspath, 1));
3017     }
3018
3019   if (aspath != attr->aspath)
3020     aspath_free (aspath);
3021
3022   if ( send_as4_aggregator ) 
3023     {
3024       assert (attr->extra);
3025
3026       /* send AS4_AGGREGATOR, at this place */
3027       /* this section of code moved here in order to ensure the correct
3028        * *ascending* order of attributes
3029        */
3030       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3031       stream_putc (s, BGP_ATTR_AS4_AGGREGATOR);
3032       stream_putc (s, 8);
3033       stream_putl (s, attr->extra->aggregator_as);
3034       stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
3035     }
3036
3037   if ((afi == AFI_IP || afi == AFI_IP6) &&
3038       (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN))
3039     {
3040         /* Tunnel Encap attribute */
3041         bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
3042     }
3043
3044   /* Unknown transit attribute. */
3045   if (attr->extra && attr->extra->transit)
3046     stream_put (s, attr->extra->transit->val, attr->extra->transit->length);
3047
3048   /* Return total size of attribute. */
3049   return stream_get_endp (s) - cp;
3050 }
3051
3052 size_t
3053 bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi)
3054 {
3055   unsigned long attrlen_pnt;
3056
3057   /* Set extended bit always to encode the attribute length as 2 bytes */
3058   stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
3059   stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
3060
3061   attrlen_pnt = stream_get_endp (s);
3062   stream_putw (s, 0);           /* Length of this attribute. */
3063
3064   stream_putw (s, afi);
3065   stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
3066   return attrlen_pnt;
3067 }
3068
3069 void
3070 bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
3071                              afi_t afi, safi_t safi, struct prefix_rd *prd,
3072                              u_char *tag)
3073 {
3074   bgp_packet_mpattr_prefix (s, afi, safi, p, prd, tag);
3075 }
3076
3077 void
3078 bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt)
3079 {
3080   bgp_packet_mpattr_end (s, attrlen_pnt);
3081 }
3082
3083 /* Initialization of attribute. */
3084 void
3085 bgp_attr_init (void)
3086 {
3087   aspath_init ();
3088   attrhash_init ();
3089   community_init ();
3090   ecommunity_init ();
3091   lcommunity_init ();
3092   cluster_init ();
3093   transit_init ();
3094 }
3095
3096 void
3097 bgp_attr_finish (void)
3098 {
3099   aspath_finish ();
3100   attrhash_finish ();
3101   community_finish ();
3102   ecommunity_finish ();
3103   lcommunity_finish ();
3104   cluster_finish ();
3105   transit_finish ();
3106 }
3107
3108 /* Make attribute packet. */
3109 void
3110 bgp_dump_routes_attr (struct stream *s, struct attr *attr, 
3111                       struct prefix *prefix)
3112 {
3113   unsigned long cp;
3114   unsigned long len;
3115   size_t aspath_lenp;
3116   struct aspath *aspath;
3117
3118   /* Remember current pointer. */
3119   cp = stream_get_endp (s);
3120
3121   /* Place holder of length. */
3122   stream_putw (s, 0);
3123
3124   /* Origin attribute. */
3125   stream_putc (s, BGP_ATTR_FLAG_TRANS);
3126   stream_putc (s, BGP_ATTR_ORIGIN);
3127   stream_putc (s, 1);
3128   stream_putc (s, attr->origin);
3129
3130   aspath = attr->aspath;
3131   
3132   stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3133   stream_putc (s, BGP_ATTR_AS_PATH);
3134   aspath_lenp = stream_get_endp (s);
3135   stream_putw (s, 0);
3136   
3137   stream_putw_at (s, aspath_lenp, aspath_put (s, aspath, 1));
3138
3139   /* Nexthop attribute. */
3140   /* If it's an IPv6 prefix, don't dump the IPv4 nexthop to save space */
3141   if(prefix != NULL
3142      && prefix->family != AF_INET6
3143      )
3144     {
3145       stream_putc (s, BGP_ATTR_FLAG_TRANS);
3146       stream_putc (s, BGP_ATTR_NEXT_HOP);
3147       stream_putc (s, 4);
3148       stream_put_ipv4 (s, attr->nexthop.s_addr);
3149     }
3150
3151   /* MED attribute. */
3152   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
3153     {
3154       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
3155       stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC);
3156       stream_putc (s, 4);
3157       stream_putl (s, attr->med);
3158     }
3159
3160   /* Local preference. */
3161   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
3162     {
3163       stream_putc (s, BGP_ATTR_FLAG_TRANS);
3164       stream_putc (s, BGP_ATTR_LOCAL_PREF);
3165       stream_putc (s, 4);
3166       stream_putl (s, attr->local_pref);
3167     }
3168
3169   /* Atomic aggregate. */
3170   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))
3171     {
3172       stream_putc (s, BGP_ATTR_FLAG_TRANS);
3173       stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE);
3174       stream_putc (s, 0);
3175     }
3176
3177   /* Aggregator. */
3178   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR))
3179     {
3180       assert (attr->extra);
3181       stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3182       stream_putc (s, BGP_ATTR_AGGREGATOR);
3183       stream_putc (s, 8);
3184       stream_putl (s, attr->extra->aggregator_as);
3185       stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
3186     }
3187
3188   /* Community attribute. */
3189   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES))
3190     {
3191       if (attr->community->size * 4 > 255)
3192         {
3193           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3194           stream_putc (s, BGP_ATTR_COMMUNITIES);
3195           stream_putw (s, attr->community->size * 4);
3196         }
3197       else
3198         {
3199           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3200           stream_putc (s, BGP_ATTR_COMMUNITIES);
3201           stream_putc (s, attr->community->size * 4);
3202         }
3203       stream_put (s, attr->community->val, attr->community->size * 4);
3204     }
3205
3206     /* Large Community attribute. */
3207   if (attr->extra && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES))
3208     {
3209       if (attr->extra->lcommunity->size * 12 > 255)
3210         {
3211           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3212           stream_putc (s, BGP_ATTR_COMMUNITIES);
3213           stream_putw (s, attr->extra->lcommunity->size * 12);
3214         }
3215       else
3216         {
3217           stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3218           stream_putc (s, BGP_ATTR_COMMUNITIES);
3219           stream_putc (s, attr->extra->lcommunity->size * 12);
3220         }
3221
3222       stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12);
3223     }
3224
3225   /* Add a MP_NLRI attribute to dump the IPv6 next hop */
3226   if (prefix != NULL && prefix->family == AF_INET6 && attr->extra &&
3227      (attr->extra->mp_nexthop_len == 16 || attr->extra->mp_nexthop_len == 32) )
3228     {
3229       int sizep;
3230       struct attr_extra *attre = attr->extra;
3231       
3232       stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
3233       stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
3234       sizep = stream_get_endp (s);
3235
3236       /* MP header */
3237       stream_putc (s, 0);               /* Marker: Attribute length. */
3238       stream_putw(s, AFI_IP6);          /* AFI */
3239       stream_putc(s, SAFI_UNICAST);     /* SAFI */
3240
3241       /* Next hop */
3242       stream_putc(s, attre->mp_nexthop_len);
3243       stream_put(s, &attre->mp_nexthop_global, 16);
3244       if (attre->mp_nexthop_len == 32)
3245         stream_put(s, &attre->mp_nexthop_local, 16);
3246
3247       /* SNPA */
3248       stream_putc(s, 0);
3249
3250       /* Prefix */
3251       stream_put_prefix(s, prefix);
3252
3253       /* Set MP attribute length. */
3254       stream_putc_at (s, sizep, (stream_get_endp (s) - sizep) - 1);
3255     }
3256
3257   /* Return total size of attribute. */
3258   len = stream_get_endp (s) - cp - 2;
3259   stream_putw_at (s, cp, len);
3260 }