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