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