]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_attr.c
Merge branch 'frr/pull/567'
[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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
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 /* Create the attributes for an aggregate */
972 struct attr *
973 bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin,
974 struct aspath *aspath,
975 struct community *community, int as_set,
976 u_char atomic_aggregate)
977 {
978 struct attr attr;
979 struct attr *new;
980 struct attr_extra attre;
981
982 memset (&attr, 0, sizeof (struct attr));
983 memset (&attre, 0, sizeof (struct attr_extra));
984 attr.extra = &attre;
985
986 /* Origin attribute. */
987 attr.origin = origin;
988 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);
989
990 /* AS path attribute. */
991 if (aspath)
992 attr.aspath = aspath_intern (aspath);
993 else
994 attr.aspath = aspath_empty ();
995 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
996
997 /* Next hop attribute. */
998 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
999
1000 if (community)
1001 {
1002 attr.community = community;
1003 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1004 }
1005
1006 attre.weight = BGP_ATTR_DEFAULT_WEIGHT;
1007 attre.mp_nexthop_len = IPV6_MAX_BYTELEN;
1008 if (! as_set || atomic_aggregate)
1009 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1010 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1011 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
1012 attre.aggregator_as = bgp->confed_id;
1013 else
1014 attre.aggregator_as = bgp->as;
1015 attre.aggregator_addr = bgp->router_id;
1016
1017 new = bgp_attr_intern (&attr);
1018
1019 aspath_unintern (&new->aspath);
1020 return new;
1021 }
1022
1023 /* Unintern just the sub-components of the attr, but not the attr */
1024 void
1025 bgp_attr_unintern_sub (struct attr *attr)
1026 {
1027 /* aspath refcount shoud be decrement. */
1028 if (attr->aspath)
1029 aspath_unintern (&attr->aspath);
1030 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH));
1031
1032 if (attr->community)
1033 community_unintern (&attr->community);
1034 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1035
1036 if (attr->extra)
1037 {
1038 if (attr->extra->ecommunity)
1039 ecommunity_unintern (&attr->extra->ecommunity);
1040 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES));
1041
1042 if (attr->extra->lcommunity)
1043 lcommunity_unintern (&attr->extra->lcommunity);
1044 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
1045
1046 if (attr->extra->cluster)
1047 cluster_unintern (attr->extra->cluster);
1048 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST));
1049
1050 if (attr->extra->transit)
1051 transit_unintern (attr->extra->transit);
1052
1053 if (attr->extra->encap_subtlvs)
1054 encap_unintern (&attr->extra->encap_subtlvs, ENCAP_SUBTLV_TYPE);
1055
1056 #if ENABLE_BGP_VNC
1057 if (attr->extra->vnc_subtlvs)
1058 encap_unintern (&attr->extra->vnc_subtlvs, VNC_SUBTLV_TYPE);
1059 #endif
1060 }
1061 }
1062
1063 /* Free bgp attribute and aspath. */
1064 void
1065 bgp_attr_unintern (struct attr **pattr)
1066 {
1067 struct attr *attr = *pattr;
1068 struct attr *ret;
1069 struct attr tmp;
1070 struct attr_extra tmp_extra;
1071
1072 /* Decrement attribute reference. */
1073 attr->refcnt--;
1074
1075 tmp = *attr;
1076
1077 if (attr->extra)
1078 {
1079 tmp.extra = &tmp_extra;
1080 memcpy (tmp.extra, attr->extra, sizeof (struct attr_extra));
1081 }
1082
1083 /* If reference becomes zero then free attribute object. */
1084 if (attr->refcnt == 0)
1085 {
1086 ret = hash_release (attrhash, attr);
1087 assert (ret != NULL);
1088 bgp_attr_extra_free (attr);
1089 XFREE (MTYPE_ATTR, attr);
1090 *pattr = NULL;
1091 }
1092
1093 bgp_attr_unintern_sub (&tmp);
1094 }
1095
1096 void
1097 bgp_attr_flush (struct attr *attr)
1098 {
1099 if (attr->aspath && ! attr->aspath->refcnt)
1100 {
1101 aspath_free (attr->aspath);
1102 attr->aspath = NULL;
1103 }
1104 if (attr->community && ! attr->community->refcnt)
1105 {
1106 community_free (attr->community);
1107 attr->community = NULL;
1108 }
1109 if (attr->extra)
1110 {
1111 struct attr_extra *attre = attr->extra;
1112
1113 if (attre->ecommunity && ! attre->ecommunity->refcnt)
1114 ecommunity_free (&attre->ecommunity);
1115 if (attre->lcommunity && ! attre->lcommunity->refcnt)
1116 lcommunity_free (&attre->lcommunity);
1117 if (attre->cluster && ! attre->cluster->refcnt)
1118 {
1119 cluster_free (attre->cluster);
1120 attre->cluster = NULL;
1121 }
1122 if (attre->transit && ! attre->transit->refcnt)
1123 {
1124 transit_free (attre->transit);
1125 attre->transit = NULL;
1126 }
1127 if (attre->encap_subtlvs && ! attre->encap_subtlvs->refcnt)
1128 {
1129 encap_free(attre->encap_subtlvs);
1130 attre->encap_subtlvs = NULL;
1131 }
1132 #if ENABLE_BGP_VNC
1133 if (attre->vnc_subtlvs && ! attre->vnc_subtlvs->refcnt)
1134 {
1135 encap_free(attre->vnc_subtlvs);
1136 attre->vnc_subtlvs = NULL;
1137 }
1138 #endif
1139 }
1140 }
1141
1142 /* Implement draft-scudder-idr-optional-transitive behaviour and
1143 * avoid resetting sessions for malformed attributes which are
1144 * are partial/optional and hence where the error likely was not
1145 * introduced by the sending neighbour.
1146 */
1147 static bgp_attr_parse_ret_t
1148 bgp_attr_malformed (struct bgp_attr_parser_args *args, u_char subcode,
1149 bgp_size_t length)
1150 {
1151 struct peer *const peer = args->peer;
1152 const u_int8_t flags = args->flags;
1153 /* startp and length must be special-cased, as whether or not to
1154 * send the attribute data with the NOTIFY depends on the error,
1155 * the caller therefore signals this with the seperate length argument
1156 */
1157 u_char *notify_datap = (length > 0 ? args->startp : NULL);
1158
1159 /* Only relax error handling for eBGP peers */
1160 if (peer->sort != BGP_PEER_EBGP)
1161 {
1162 bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, subcode,
1163 notify_datap, length);
1164 return BGP_ATTR_PARSE_ERROR;
1165
1166 }
1167
1168 /* Adjust the stream getp to the end of the attribute, in case we can
1169 * still proceed but the caller hasn't read all the attribute.
1170 */
1171 stream_set_getp (BGP_INPUT (peer),
1172 (args->startp - STREAM_DATA (BGP_INPUT (peer)))
1173 + args->total);
1174
1175 switch (args->type) {
1176 /* where an attribute is relatively inconsequential, e.g. it does not
1177 * affect route selection, and can be safely ignored, then any such
1178 * attributes which are malformed should just be ignored and the route
1179 * processed as normal.
1180 */
1181 case BGP_ATTR_AS4_AGGREGATOR:
1182 case BGP_ATTR_AGGREGATOR:
1183 case BGP_ATTR_ATOMIC_AGGREGATE:
1184 return BGP_ATTR_PARSE_PROCEED;
1185
1186 /* Core attributes, particularly ones which may influence route
1187 * selection, should always cause session resets
1188 */
1189 case BGP_ATTR_ORIGIN:
1190 case BGP_ATTR_AS_PATH:
1191 case BGP_ATTR_NEXT_HOP:
1192 case BGP_ATTR_MULTI_EXIT_DISC:
1193 case BGP_ATTR_LOCAL_PREF:
1194 case BGP_ATTR_COMMUNITIES:
1195 case BGP_ATTR_ORIGINATOR_ID:
1196 case BGP_ATTR_CLUSTER_LIST:
1197 case BGP_ATTR_MP_REACH_NLRI:
1198 case BGP_ATTR_MP_UNREACH_NLRI:
1199 case BGP_ATTR_EXT_COMMUNITIES:
1200 bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, subcode,
1201 notify_datap, length);
1202 return BGP_ATTR_PARSE_ERROR;
1203 }
1204
1205 /* Partial optional attributes that are malformed should not cause
1206 * the whole session to be reset. Instead treat it as a withdrawal
1207 * of the routes, if possible.
1208 */
1209 if (CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS)
1210 && CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
1211 && CHECK_FLAG (flags, BGP_ATTR_FLAG_PARTIAL))
1212 return BGP_ATTR_PARSE_WITHDRAW;
1213
1214 /* default to reset */
1215 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1216 }
1217
1218 /* Find out what is wrong with the path attribute flag bits and log the error.
1219 "Flag bits" here stand for Optional, Transitive and Partial, but not for
1220 Extended Length. Checking O/T/P bits at once implies, that the attribute
1221 being diagnosed is defined by RFC as either a "well-known" or an "optional,
1222 non-transitive" attribute. */
1223 static void
1224 bgp_attr_flags_diagnose (struct bgp_attr_parser_args *args,
1225 u_int8_t desired_flags /* how RFC says it must be */
1226 )
1227 {
1228 u_char seen = 0, i;
1229 u_char real_flags = args->flags;
1230 const u_int8_t attr_code = args->type;
1231
1232 desired_flags &= ~BGP_ATTR_FLAG_EXTLEN;
1233 real_flags &= ~BGP_ATTR_FLAG_EXTLEN;
1234 for (i = 0; i <= 2; i++) /* O,T,P, but not E */
1235 if
1236 (
1237 CHECK_FLAG (desired_flags, attr_flag_str[i].key) !=
1238 CHECK_FLAG (real_flags, attr_flag_str[i].key)
1239 )
1240 {
1241 zlog_err ("%s attribute must%s be flagged as \"%s\"",
1242 LOOKUP (attr_str, attr_code),
1243 CHECK_FLAG (desired_flags, attr_flag_str[i].key) ? "" : " not",
1244 attr_flag_str[i].str);
1245 seen = 1;
1246 }
1247 if (!seen)
1248 {
1249 zlog_debug ("Strange, %s called for attr %s, but no problem found with flags"
1250 " (real flags 0x%x, desired 0x%x)",
1251 __func__, LOOKUP (attr_str, attr_code),
1252 real_flags, desired_flags);
1253 }
1254 }
1255
1256 /* Required flags for attributes. EXTLEN will be masked off when testing,
1257 * as will PARTIAL for optional+transitive attributes.
1258 */
1259 const u_int8_t attr_flags_values [] = {
1260 [BGP_ATTR_ORIGIN] = BGP_ATTR_FLAG_TRANS,
1261 [BGP_ATTR_AS_PATH] = BGP_ATTR_FLAG_TRANS,
1262 [BGP_ATTR_NEXT_HOP] = BGP_ATTR_FLAG_TRANS,
1263 [BGP_ATTR_MULTI_EXIT_DISC] = BGP_ATTR_FLAG_OPTIONAL,
1264 [BGP_ATTR_LOCAL_PREF] = BGP_ATTR_FLAG_TRANS,
1265 [BGP_ATTR_ATOMIC_AGGREGATE] = BGP_ATTR_FLAG_TRANS,
1266 [BGP_ATTR_AGGREGATOR] = BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
1267 [BGP_ATTR_COMMUNITIES] = BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
1268 [BGP_ATTR_ORIGINATOR_ID] = BGP_ATTR_FLAG_OPTIONAL,
1269 [BGP_ATTR_CLUSTER_LIST] = BGP_ATTR_FLAG_OPTIONAL,
1270 [BGP_ATTR_MP_REACH_NLRI] = BGP_ATTR_FLAG_OPTIONAL,
1271 [BGP_ATTR_MP_UNREACH_NLRI] = BGP_ATTR_FLAG_OPTIONAL,
1272 [BGP_ATTR_EXT_COMMUNITIES] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1273 [BGP_ATTR_AS4_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1274 [BGP_ATTR_AS4_AGGREGATOR] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1275 [BGP_ATTR_LARGE_COMMUNITIES]= BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1276 [BGP_ATTR_PREFIX_SID] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1277 };
1278 static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
1279
1280 static int
1281 bgp_attr_flag_invalid (struct bgp_attr_parser_args *args)
1282 {
1283 u_int8_t mask = BGP_ATTR_FLAG_EXTLEN;
1284 const u_int8_t flags = args->flags;
1285 const u_int8_t attr_code = args->type;
1286
1287 /* there may be attributes we don't know about */
1288 if (attr_code > attr_flags_values_max)
1289 return 0;
1290 if (attr_flags_values[attr_code] == 0)
1291 return 0;
1292
1293 /* RFC4271, "For well-known attributes, the Transitive bit MUST be set to
1294 * 1."
1295 */
1296 if (!CHECK_FLAG (BGP_ATTR_FLAG_OPTIONAL, flags)
1297 && !CHECK_FLAG (BGP_ATTR_FLAG_TRANS, flags))
1298 {
1299 zlog_err ("%s well-known attributes must have transitive flag set (%x)",
1300 LOOKUP (attr_str, attr_code), flags);
1301 return 1;
1302 }
1303
1304 /* "For well-known attributes and for optional non-transitive attributes,
1305 * the Partial bit MUST be set to 0."
1306 */
1307 if (CHECK_FLAG (flags, BGP_ATTR_FLAG_PARTIAL))
1308 {
1309 if (!CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL))
1310 {
1311 zlog_err ("%s well-known attribute "
1312 "must NOT have the partial flag set (%x)",
1313 LOOKUP (attr_str, attr_code), flags);
1314 return 1;
1315 }
1316 if (CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
1317 && !CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS))
1318 {
1319 zlog_err ("%s optional + transitive attribute "
1320 "must NOT have the partial flag set (%x)",
1321 LOOKUP (attr_str, attr_code), flags);
1322 return 1;
1323 }
1324 }
1325
1326 /* Optional transitive attributes may go through speakers that don't
1327 * reocgnise them and set the Partial bit.
1328 */
1329 if (CHECK_FLAG (flags, BGP_ATTR_FLAG_OPTIONAL)
1330 && CHECK_FLAG (flags, BGP_ATTR_FLAG_TRANS))
1331 SET_FLAG (mask, BGP_ATTR_FLAG_PARTIAL);
1332
1333 if ((flags & ~mask)
1334 == attr_flags_values[attr_code])
1335 return 0;
1336
1337 bgp_attr_flags_diagnose (args, attr_flags_values[attr_code]);
1338 return 1;
1339 }
1340
1341 /* Get origin attribute of the update message. */
1342 static bgp_attr_parse_ret_t
1343 bgp_attr_origin (struct bgp_attr_parser_args *args)
1344 {
1345 struct peer *const peer = args->peer;
1346 struct attr *const attr = args->attr;
1347 const bgp_size_t length = args->length;
1348
1349 /* If any recognized attribute has Attribute Length that conflicts
1350 with the expected length (based on the attribute type code), then
1351 the Error Subcode is set to Attribute Length Error. The Data
1352 field contains the erroneous attribute (type, length and
1353 value). */
1354 if (length != 1)
1355 {
1356 zlog_err ("Origin attribute length is not one %d", length);
1357 return bgp_attr_malformed (args,
1358 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1359 args->total);
1360 }
1361
1362 /* Fetch origin attribute. */
1363 attr->origin = stream_getc (BGP_INPUT (peer));
1364
1365 /* If the ORIGIN attribute has an undefined value, then the Error
1366 Subcode is set to Invalid Origin Attribute. The Data field
1367 contains the unrecognized attribute (type, length and value). */
1368 if ((attr->origin != BGP_ORIGIN_IGP)
1369 && (attr->origin != BGP_ORIGIN_EGP)
1370 && (attr->origin != BGP_ORIGIN_INCOMPLETE))
1371 {
1372 zlog_err ("Origin attribute value is invalid %d", attr->origin);
1373 return bgp_attr_malformed (args,
1374 BGP_NOTIFY_UPDATE_INVAL_ORIGIN,
1375 args->total);
1376 }
1377
1378 /* Set oring attribute flag. */
1379 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);
1380
1381 return 0;
1382 }
1383
1384 /* Parse AS path information. This function is wrapper of
1385 aspath_parse. */
1386 static int
1387 bgp_attr_aspath (struct bgp_attr_parser_args *args)
1388 {
1389 struct attr *const attr = args->attr;
1390 struct peer *const peer = args->peer;
1391 const bgp_size_t length = args->length;
1392
1393 /*
1394 * peer with AS4 => will get 4Byte ASnums
1395 * otherwise, will get 16 Bit
1396 */
1397 attr->aspath = aspath_parse (peer->ibuf, length,
1398 CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV));
1399
1400 /* In case of IBGP, length will be zero. */
1401 if (! attr->aspath)
1402 {
1403 zlog_err ("Malformed AS path from %s, length is %d", peer->host, length);
1404 return bgp_attr_malformed (args, BGP_NOTIFY_UPDATE_MAL_AS_PATH, 0);
1405 }
1406
1407 /* Set aspath attribute flag. */
1408 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
1409
1410 return BGP_ATTR_PARSE_PROCEED;
1411 }
1412
1413 static bgp_attr_parse_ret_t
1414 bgp_attr_aspath_check (struct peer *const peer, struct attr *const attr)
1415 {
1416 /* These checks were part of bgp_attr_aspath, but with
1417 * as4 we should to check aspath things when
1418 * aspath synthesizing with as4_path has already taken place.
1419 * Otherwise we check ASPATH and use the synthesized thing, and that is
1420 * not right.
1421 * So do the checks later, i.e. here
1422 */
1423 struct bgp *bgp = peer->bgp;
1424 struct aspath *aspath;
1425
1426 /* Confederation sanity check. */
1427 if ((peer->sort == BGP_PEER_CONFED && ! aspath_left_confed_check (attr->aspath)) ||
1428 (peer->sort == BGP_PEER_EBGP && aspath_confed_check (attr->aspath)))
1429 {
1430 zlog_err ("Malformed AS path from %s", peer->host);
1431 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1432 BGP_NOTIFY_UPDATE_MAL_AS_PATH);
1433 return BGP_ATTR_PARSE_ERROR;
1434 }
1435
1436 /* First AS check for EBGP. */
1437 if (bgp != NULL && bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
1438 {
1439 if (peer->sort == BGP_PEER_EBGP
1440 && ! aspath_firstas_check (attr->aspath, peer->as))
1441 {
1442 zlog_err ("%s incorrect first AS (must be %u)", peer->host, peer->as);
1443 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1444 BGP_NOTIFY_UPDATE_MAL_AS_PATH);
1445 return BGP_ATTR_PARSE_ERROR;
1446 }
1447 }
1448
1449 /* local-as prepend */
1450 if (peer->change_local_as &&
1451 ! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
1452 {
1453 aspath = aspath_dup (attr->aspath);
1454 aspath = aspath_add_seq (aspath, peer->change_local_as);
1455 aspath_unintern (&attr->aspath);
1456 attr->aspath = aspath_intern (aspath);
1457 }
1458
1459 return BGP_ATTR_PARSE_PROCEED;
1460 }
1461
1462 /* Parse AS4 path information. This function is another wrapper of
1463 aspath_parse. */
1464 static int
1465 bgp_attr_as4_path (struct bgp_attr_parser_args *args, struct aspath **as4_path)
1466 {
1467 struct peer *const peer = args->peer;
1468 struct attr *const attr = args->attr;
1469 const bgp_size_t length = args->length;
1470
1471 *as4_path = aspath_parse (peer->ibuf, length, 1);
1472
1473 /* In case of IBGP, length will be zero. */
1474 if (!*as4_path)
1475 {
1476 zlog_err ("Malformed AS4 path from %s, length is %d", peer->host, length);
1477 return bgp_attr_malformed (args,
1478 BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1479 0);
1480 }
1481
1482 /* Set aspath attribute flag. */
1483 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
1484
1485 return BGP_ATTR_PARSE_PROCEED;
1486 }
1487
1488 /* Nexthop attribute. */
1489 static bgp_attr_parse_ret_t
1490 bgp_attr_nexthop (struct bgp_attr_parser_args *args)
1491 {
1492 struct peer *const peer = args->peer;
1493 struct attr *const attr = args->attr;
1494 const bgp_size_t length = args->length;
1495
1496 in_addr_t nexthop_h, nexthop_n;
1497
1498 /* Check nexthop attribute length. */
1499 if (length != 4)
1500 {
1501 zlog_err ("Nexthop attribute length isn't four [%d]", length);
1502
1503 return bgp_attr_malformed (args,
1504 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1505 args->total);
1506 }
1507
1508 /* According to section 6.3 of RFC4271, syntactically incorrect NEXT_HOP
1509 attribute must result in a NOTIFICATION message (this is implemented below).
1510 At the same time, semantically incorrect NEXT_HOP is more likely to be just
1511 logged locally (this is implemented somewhere else). The UPDATE message
1512 gets ignored in any of these cases. */
1513 nexthop_n = stream_get_ipv4 (peer->ibuf);
1514 nexthop_h = ntohl (nexthop_n);
1515 if ((IPV4_NET0 (nexthop_h) || IPV4_NET127 (nexthop_h) || IPV4_CLASS_DE (nexthop_h))
1516 && !BGP_DEBUG (allow_martians, ALLOW_MARTIANS)) /* loopbacks may be used in testing */
1517 {
1518 char buf[INET_ADDRSTRLEN];
1519 inet_ntop (AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN);
1520 zlog_err ("Martian nexthop %s", buf);
1521 return bgp_attr_malformed (args,
1522 BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP,
1523 args->total);
1524 }
1525
1526 attr->nexthop.s_addr = nexthop_n;
1527 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1528
1529 return BGP_ATTR_PARSE_PROCEED;
1530 }
1531
1532 /* MED atrribute. */
1533 static bgp_attr_parse_ret_t
1534 bgp_attr_med (struct bgp_attr_parser_args *args)
1535 {
1536 struct peer *const peer = args->peer;
1537 struct attr *const attr = args->attr;
1538 const bgp_size_t length = args->length;
1539
1540 /* Length check. */
1541 if (length != 4)
1542 {
1543 zlog_err ("MED attribute length isn't four [%d]", length);
1544
1545 return bgp_attr_malformed (args,
1546 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1547 args->total);
1548 }
1549
1550 attr->med = stream_getl (peer->ibuf);
1551
1552 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1553
1554 return BGP_ATTR_PARSE_PROCEED;
1555 }
1556
1557 /* Local preference attribute. */
1558 static bgp_attr_parse_ret_t
1559 bgp_attr_local_pref (struct bgp_attr_parser_args *args)
1560 {
1561 struct peer *const peer = args->peer;
1562 struct attr *const attr = args->attr;
1563 const bgp_size_t length = args->length;
1564
1565 /* Length check. */
1566 if (length != 4)
1567 {
1568 zlog_err ("LOCAL_PREF attribute length isn't 4 [%u]", length);
1569 return bgp_attr_malformed (args,
1570 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1571 args->total);
1572 }
1573
1574 /* If it is contained in an UPDATE message that is received from an
1575 external peer, then this attribute MUST be ignored by the
1576 receiving speaker. */
1577 if (peer->sort == BGP_PEER_EBGP)
1578 {
1579 stream_forward_getp (peer->ibuf, length);
1580 return BGP_ATTR_PARSE_PROCEED;
1581 }
1582
1583 attr->local_pref = stream_getl (peer->ibuf);
1584
1585 /* Set atomic aggregate flag. */
1586 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1587
1588 return BGP_ATTR_PARSE_PROCEED;
1589 }
1590
1591 /* Atomic aggregate. */
1592 static int
1593 bgp_attr_atomic (struct bgp_attr_parser_args *args)
1594 {
1595 struct attr *const attr = args->attr;
1596 const bgp_size_t length = args->length;
1597
1598 /* Length check. */
1599 if (length != 0)
1600 {
1601 zlog_err ("ATOMIC_AGGREGATE attribute length isn't 0 [%u]", length);
1602 return bgp_attr_malformed (args,
1603 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1604 args->total);
1605 }
1606
1607 /* Set atomic aggregate flag. */
1608 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1609
1610 return BGP_ATTR_PARSE_PROCEED;
1611 }
1612
1613 /* Aggregator attribute */
1614 static int
1615 bgp_attr_aggregator (struct bgp_attr_parser_args *args)
1616 {
1617 struct peer *const peer = args->peer;
1618 struct attr *const attr = args->attr;
1619 const bgp_size_t length = args->length;
1620
1621 int wantedlen = 6;
1622 struct attr_extra *attre = bgp_attr_extra_get (attr);
1623
1624 /* peer with AS4 will send 4 Byte AS, peer without will send 2 Byte */
1625 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV))
1626 wantedlen = 8;
1627
1628 if (length != wantedlen)
1629 {
1630 zlog_err ("AGGREGATOR attribute length isn't %u [%u]", wantedlen, length);
1631 return bgp_attr_malformed (args,
1632 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1633 args->total);
1634 }
1635
1636 if ( CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV ) )
1637 attre->aggregator_as = stream_getl (peer->ibuf);
1638 else
1639 attre->aggregator_as = stream_getw (peer->ibuf);
1640 attre->aggregator_addr.s_addr = stream_get_ipv4 (peer->ibuf);
1641
1642 /* Set atomic aggregate flag. */
1643 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1644
1645 return BGP_ATTR_PARSE_PROCEED;
1646 }
1647
1648 /* New Aggregator attribute */
1649 static bgp_attr_parse_ret_t
1650 bgp_attr_as4_aggregator (struct bgp_attr_parser_args *args,
1651 as_t *as4_aggregator_as,
1652 struct in_addr *as4_aggregator_addr)
1653 {
1654 struct peer *const peer = args->peer;
1655 struct attr *const attr = args->attr;
1656 const bgp_size_t length = args->length;
1657
1658 if (length != 8)
1659 {
1660 zlog_err ("New Aggregator length is not 8 [%d]", length);
1661 return bgp_attr_malformed (args,
1662 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1663 0);
1664 }
1665
1666 *as4_aggregator_as = stream_getl (peer->ibuf);
1667 as4_aggregator_addr->s_addr = stream_get_ipv4 (peer->ibuf);
1668
1669 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_AGGREGATOR);
1670
1671 return BGP_ATTR_PARSE_PROCEED;
1672 }
1673
1674 /* Munge Aggregator and New-Aggregator, AS_PATH and NEW_AS_PATH.
1675 */
1676 static bgp_attr_parse_ret_t
1677 bgp_attr_munge_as4_attrs (struct peer *const peer,
1678 struct attr *const attr,
1679 struct aspath *as4_path, as_t as4_aggregator,
1680 struct in_addr *as4_aggregator_addr)
1681 {
1682 int ignore_as4_path = 0;
1683 struct aspath *newpath;
1684 struct attr_extra *attre = attr->extra;
1685
1686 if (!attr->aspath)
1687 {
1688 /* NULL aspath shouldn't be possible as bgp_attr_parse should have
1689 * checked that all well-known, mandatory attributes were present.
1690 *
1691 * Can only be a problem with peer itself - hard error
1692 */
1693 return BGP_ATTR_PARSE_ERROR;
1694 }
1695
1696 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV))
1697 {
1698 /* peer can do AS4, so we ignore AS4_PATH and AS4_AGGREGATOR
1699 * if given.
1700 * It is worth a warning though, because the peer really
1701 * should not send them
1702 */
1703 if (BGP_DEBUG(as4, AS4))
1704 {
1705 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))
1706 zlog_debug ("[AS4] %s %s AS4_PATH",
1707 peer->host, "AS4 capable peer, yet it sent");
1708
1709 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR)))
1710 zlog_debug ("[AS4] %s %s AS4_AGGREGATOR",
1711 peer->host, "AS4 capable peer, yet it sent");
1712 }
1713
1714 return BGP_ATTR_PARSE_PROCEED;
1715 }
1716
1717 /* We have a asn16 peer. First, look for AS4_AGGREGATOR
1718 * because that may override AS4_PATH
1719 */
1720 if (attr->flag & (ATTR_FLAG_BIT (BGP_ATTR_AS4_AGGREGATOR) ) )
1721 {
1722 if (attr->flag & (ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR) ) )
1723 {
1724 assert (attre);
1725
1726 /* received both.
1727 * if the as_number in aggregator is not AS_TRANS,
1728 * then AS4_AGGREGATOR and AS4_PATH shall be ignored
1729 * and the Aggregator shall be taken as
1730 * info on the aggregating node, and the AS_PATH
1731 * shall be taken as the AS_PATH
1732 * otherwise
1733 * the Aggregator shall be ignored and the
1734 * AS4_AGGREGATOR shall be taken as the
1735 * Aggregating node and the AS_PATH is to be
1736 * constructed "as in all other cases"
1737 */
1738 if (attre->aggregator_as != BGP_AS_TRANS)
1739 {
1740 /* ignore */
1741 if ( BGP_DEBUG(as4, AS4))
1742 zlog_debug ("[AS4] %s BGP not AS4 capable peer"
1743 " send AGGREGATOR != AS_TRANS and"
1744 " AS4_AGGREGATOR, so ignore"
1745 " AS4_AGGREGATOR and AS4_PATH", peer->host);
1746 ignore_as4_path = 1;
1747 }
1748 else
1749 {
1750 /* "New_aggregator shall be taken as aggregator" */
1751 attre->aggregator_as = as4_aggregator;
1752 attre->aggregator_addr.s_addr = as4_aggregator_addr->s_addr;
1753 }
1754 }
1755 else
1756 {
1757 /* We received a AS4_AGGREGATOR but no AGGREGATOR.
1758 * That is bogus - but reading the conditions
1759 * we have to handle AS4_AGGREGATOR as if it were
1760 * AGGREGATOR in that case
1761 */
1762 if ( BGP_DEBUG(as4, AS4))
1763 zlog_debug ("[AS4] %s BGP not AS4 capable peer send"
1764 " AS4_AGGREGATOR but no AGGREGATOR, will take"
1765 " it as if AGGREGATOR with AS_TRANS had been there", peer->host);
1766 (attre = bgp_attr_extra_get (attr))->aggregator_as = as4_aggregator;
1767 /* sweep it under the carpet and simulate a "good" AGGREGATOR */
1768 attr->flag |= (ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR));
1769 }
1770 }
1771
1772 /* need to reconcile NEW_AS_PATH and AS_PATH */
1773 if (!ignore_as4_path && (attr->flag & (ATTR_FLAG_BIT( BGP_ATTR_AS4_PATH))))
1774 {
1775 newpath = aspath_reconcile_as4 (attr->aspath, as4_path);
1776 aspath_unintern (&attr->aspath);
1777 attr->aspath = aspath_intern (newpath);
1778 }
1779 return BGP_ATTR_PARSE_PROCEED;
1780 }
1781
1782 /* Community attribute. */
1783 static bgp_attr_parse_ret_t
1784 bgp_attr_community (struct bgp_attr_parser_args *args)
1785 {
1786 struct peer *const peer = args->peer;
1787 struct attr *const attr = args->attr;
1788 const bgp_size_t length = args->length;
1789
1790 if (length == 0)
1791 {
1792 attr->community = NULL;
1793 return BGP_ATTR_PARSE_PROCEED;
1794 }
1795
1796 attr->community =
1797 community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length);
1798
1799 /* XXX: fix community_parse to use stream API and remove this */
1800 stream_forward_getp (peer->ibuf, length);
1801
1802 if (!attr->community)
1803 return bgp_attr_malformed (args,
1804 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1805 args->total);
1806
1807 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1808
1809 return BGP_ATTR_PARSE_PROCEED;
1810 }
1811
1812 /* Originator ID attribute. */
1813 static bgp_attr_parse_ret_t
1814 bgp_attr_originator_id (struct bgp_attr_parser_args *args)
1815 {
1816 struct peer *const peer = args->peer;
1817 struct attr *const attr = args->attr;
1818 const bgp_size_t length = args->length;
1819
1820 /* Length check. */
1821 if (length != 4)
1822 {
1823 zlog_err ("Bad originator ID length %d", length);
1824
1825 return bgp_attr_malformed (args,
1826 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1827 args->total);
1828 }
1829
1830 (bgp_attr_extra_get (attr))->originator_id.s_addr
1831 = stream_get_ipv4 (peer->ibuf);
1832
1833 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
1834
1835 return BGP_ATTR_PARSE_PROCEED;
1836 }
1837
1838 /* Cluster list attribute. */
1839 static bgp_attr_parse_ret_t
1840 bgp_attr_cluster_list (struct bgp_attr_parser_args *args)
1841 {
1842 struct peer *const peer = args->peer;
1843 struct attr *const attr = args->attr;
1844 const bgp_size_t length = args->length;
1845
1846 /* Check length. */
1847 if (length % 4)
1848 {
1849 zlog_err ("Bad cluster list length %d", length);
1850
1851 return bgp_attr_malformed (args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1852 args->total);
1853 }
1854
1855 (bgp_attr_extra_get (attr))->cluster
1856 = cluster_parse ((struct in_addr *)stream_pnt (peer->ibuf), length);
1857
1858 /* XXX: Fix cluster_parse to use stream API and then remove this */
1859 stream_forward_getp (peer->ibuf, length);
1860
1861 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST);
1862
1863 return BGP_ATTR_PARSE_PROCEED;
1864 }
1865
1866 /* Multiprotocol reachability information parse. */
1867 int
1868 bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
1869 struct bgp_nlri *mp_update)
1870 {
1871 iana_afi_t pkt_afi;
1872 afi_t afi;
1873 safi_t pkt_safi, safi;
1874 bgp_size_t nlri_len;
1875 size_t start;
1876 struct stream *s;
1877 struct peer *const peer = args->peer;
1878 struct attr *const attr = args->attr;
1879 const bgp_size_t length = args->length;
1880 struct attr_extra *attre = bgp_attr_extra_get(attr);
1881
1882 /* Set end of packet. */
1883 s = BGP_INPUT(peer);
1884 start = stream_get_getp(s);
1885
1886 /* safe to read statically sized header? */
1887 #define BGP_MP_REACH_MIN_SIZE 5
1888 #define LEN_LEFT (length - (stream_get_getp(s) - start))
1889 if ((length > STREAM_READABLE(s)) || (length < BGP_MP_REACH_MIN_SIZE))
1890 {
1891 zlog_info ("%s: %s sent invalid length, %lu",
1892 __func__, peer->host, (unsigned long)length);
1893 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1894 }
1895
1896 /* Load AFI, SAFI. */
1897 pkt_afi = stream_getw (s);
1898 pkt_safi = stream_getc (s);
1899
1900 /* Convert AFI, SAFI to internal values, check. */
1901 if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
1902 {
1903 /* Log if AFI or SAFI is unrecognized. This is not an error unless
1904 * the attribute is otherwise malformed.
1905 */
1906 if (bgp_debug_update(peer, NULL, NULL, 0))
1907 zlog_debug ("%s: MP_REACH received AFI %u or SAFI %u is unrecognized",
1908 peer->host, pkt_afi, pkt_safi);
1909 return BGP_ATTR_PARSE_ERROR;
1910 }
1911
1912 /* Get nexthop length. */
1913 attre->mp_nexthop_len = stream_getc (s);
1914
1915 if (LEN_LEFT < attre->mp_nexthop_len)
1916 {
1917 zlog_info ("%s: %s, MP nexthop length, %u, goes past end of attribute",
1918 __func__, peer->host, attre->mp_nexthop_len);
1919 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1920 }
1921
1922 /* Nexthop length check. */
1923 switch (attre->mp_nexthop_len)
1924 {
1925 case BGP_ATTR_NHLEN_IPV4:
1926 stream_get (&attre->mp_nexthop_global_in, s, IPV4_MAX_BYTELEN);
1927 /* Probably needed for RFC 2283 */
1928 if (attr->nexthop.s_addr == 0)
1929 memcpy(&attr->nexthop.s_addr, &attre->mp_nexthop_global_in, IPV4_MAX_BYTELEN);
1930 break;
1931 case BGP_ATTR_NHLEN_VPNV4:
1932 stream_getl (s); /* RD high */
1933 stream_getl (s); /* RD low */
1934 stream_get (&attre->mp_nexthop_global_in, s, IPV4_MAX_BYTELEN);
1935 break;
1936 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
1937 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
1938 if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL)
1939 {
1940 stream_getl (s); /* RD high */
1941 stream_getl (s); /* RD low */
1942 }
1943 stream_get (&attre->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
1944 break;
1945 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
1946 case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
1947 if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
1948 {
1949 stream_getl (s); /* RD high */
1950 stream_getl (s); /* RD low */
1951 }
1952 stream_get (&attre->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
1953 if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
1954 {
1955 stream_getl (s); /* RD high */
1956 stream_getl (s); /* RD low */
1957 }
1958 stream_get (&attre->mp_nexthop_local, s, IPV6_MAX_BYTELEN);
1959 if (! IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local))
1960 {
1961 char buf1[INET6_ADDRSTRLEN];
1962 char buf2[INET6_ADDRSTRLEN];
1963
1964 if (bgp_debug_update(peer, NULL, NULL, 1))
1965 zlog_debug ("%s rcvd nexthops %s, %s -- ignoring non-LL value",
1966 peer->host,
1967 inet_ntop (AF_INET6, &attre->mp_nexthop_global,
1968 buf1, INET6_ADDRSTRLEN),
1969 inet_ntop (AF_INET6, &attre->mp_nexthop_local,
1970 buf2, INET6_ADDRSTRLEN));
1971
1972 attre->mp_nexthop_len = IPV6_MAX_BYTELEN;
1973 }
1974 break;
1975 default:
1976 zlog_info ("%s: (%s) Wrong multiprotocol next hop length: %d",
1977 __func__, peer->host, attre->mp_nexthop_len);
1978 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1979 }
1980
1981 if (!LEN_LEFT)
1982 {
1983 zlog_info ("%s: (%s) Failed to read SNPA and NLRI(s)",
1984 __func__, peer->host);
1985 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1986 }
1987
1988 {
1989 u_char val;
1990 if ((val = stream_getc (s)))
1991 zlog_warn ("%s sent non-zero value, %u, for defunct SNPA-length field",
1992 peer->host, val);
1993 }
1994
1995 /* must have nrli_len, what is left of the attribute */
1996 nlri_len = LEN_LEFT;
1997 if ((!nlri_len) || (nlri_len > STREAM_READABLE(s)))
1998 {
1999 zlog_info ("%s: (%s) Failed to read NLRI",
2000 __func__, peer->host);
2001 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2002 }
2003
2004 mp_update->afi = afi;
2005 mp_update->safi = safi;
2006 mp_update->nlri = stream_pnt (s);
2007 mp_update->length = nlri_len;
2008
2009 stream_forward_getp (s, nlri_len);
2010
2011 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MP_REACH_NLRI);
2012
2013 return BGP_ATTR_PARSE_PROCEED;
2014 #undef LEN_LEFT
2015 }
2016
2017 /* Multiprotocol unreachable parse */
2018 int
2019 bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
2020 struct bgp_nlri *mp_withdraw)
2021 {
2022 struct stream *s;
2023 iana_afi_t pkt_afi;
2024 afi_t afi;
2025 safi_t pkt_safi, safi;
2026 u_int16_t withdraw_len;
2027 struct peer *const peer = args->peer;
2028 struct attr *const attr = args->attr;
2029 const bgp_size_t length = args->length;
2030
2031 s = peer->ibuf;
2032
2033 #define BGP_MP_UNREACH_MIN_SIZE 3
2034 if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE))
2035 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2036
2037 pkt_afi = stream_getw (s);
2038 pkt_safi = stream_getc (s);
2039
2040 /* Convert AFI, SAFI to internal values, check. */
2041 if (bgp_map_afi_safi_iana2int (pkt_afi, pkt_safi, &afi, &safi))
2042 {
2043 /* Log if AFI or SAFI is unrecognized. This is not an error unless
2044 * the attribute is otherwise malformed.
2045 */
2046 if (bgp_debug_update(peer, NULL, NULL, 0))
2047 zlog_debug ("%s: MP_UNREACH received AFI %u or SAFI %u is unrecognized",
2048 peer->host, pkt_afi, pkt_safi);
2049 return BGP_ATTR_PARSE_ERROR;
2050 }
2051
2052 withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
2053
2054 mp_withdraw->afi = afi;
2055 mp_withdraw->safi = safi;
2056 mp_withdraw->nlri = stream_pnt (s);
2057 mp_withdraw->length = withdraw_len;
2058
2059 stream_forward_getp (s, withdraw_len);
2060
2061 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI);
2062
2063 return BGP_ATTR_PARSE_PROCEED;
2064 }
2065
2066 /* Large Community attribute. */
2067 static bgp_attr_parse_ret_t
2068 bgp_attr_large_community (struct bgp_attr_parser_args *args)
2069 {
2070 struct peer *const peer = args->peer;
2071 struct attr *const attr = args->attr;
2072 const bgp_size_t length = args->length;
2073
2074 /*
2075 * Large community follows new attribute format.
2076 */
2077 if (length == 0)
2078 {
2079 if (attr->extra)
2080 attr->extra->lcommunity = NULL;
2081 /* Empty extcomm doesn't seem to be invalid per se */
2082 return BGP_ATTR_PARSE_PROCEED;
2083 }
2084
2085 (bgp_attr_extra_get (attr))->lcommunity =
2086 lcommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
2087 /* XXX: fix ecommunity_parse to use stream API */
2088 stream_forward_getp (peer->ibuf, length);
2089
2090 if (attr->extra && !attr->extra->lcommunity)
2091 return bgp_attr_malformed (args,
2092 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2093 args->total);
2094
2095 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
2096
2097 return BGP_ATTR_PARSE_PROCEED;
2098 }
2099
2100 /* Extended Community attribute. */
2101 static bgp_attr_parse_ret_t
2102 bgp_attr_ext_communities (struct bgp_attr_parser_args *args)
2103 {
2104 struct peer *const peer = args->peer;
2105 struct attr *const attr = args->attr;
2106 const bgp_size_t length = args->length;
2107
2108 if (length == 0)
2109 {
2110 if (attr->extra)
2111 attr->extra->ecommunity = NULL;
2112 /* Empty extcomm doesn't seem to be invalid per se */
2113 return BGP_ATTR_PARSE_PROCEED;
2114 }
2115
2116 (bgp_attr_extra_get (attr))->ecommunity =
2117 ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length);
2118 /* XXX: fix ecommunity_parse to use stream API */
2119 stream_forward_getp (peer->ibuf, length);
2120
2121 if (attr->extra && !attr->extra->ecommunity)
2122 return bgp_attr_malformed (args,
2123 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2124 args->total);
2125
2126 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
2127
2128 return BGP_ATTR_PARSE_PROCEED;
2129 }
2130
2131 /* Parse Tunnel Encap attribute in an UPDATE */
2132 static int
2133 bgp_attr_encap(
2134 uint8_t type,
2135 struct peer *peer, /* IN */
2136 bgp_size_t length, /* IN: attr's length field */
2137 struct attr *attr, /* IN: caller already allocated */
2138 u_char flag, /* IN: attr's flags field */
2139 u_char *startp)
2140 {
2141 bgp_size_t total;
2142 struct attr_extra *attre = NULL;
2143 struct bgp_attr_encap_subtlv *stlv_last = NULL;
2144 uint16_t tunneltype = 0;
2145
2146 total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
2147
2148 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
2149 || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL))
2150 {
2151 zlog_info ("Tunnel Encap attribute flag isn't optional and transitive %d", flag);
2152 bgp_notify_send_with_data (peer,
2153 BGP_NOTIFY_UPDATE_ERR,
2154 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
2155 startp, total);
2156 return -1;
2157 }
2158
2159 if (BGP_ATTR_ENCAP == type) {
2160 /* read outer TLV type and length */
2161 uint16_t tlv_length;
2162
2163 if (length < 4) {
2164 zlog_info ("Tunnel Encap attribute not long enough to contain outer T,L");
2165 bgp_notify_send_with_data(peer,
2166 BGP_NOTIFY_UPDATE_ERR,
2167 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2168 startp, total);
2169 return -1;
2170 }
2171 tunneltype = stream_getw (BGP_INPUT (peer));
2172 tlv_length = stream_getw (BGP_INPUT (peer));
2173 length -= 4;
2174
2175 if (tlv_length != length) {
2176 zlog_info ("%s: tlv_length(%d) != length(%d)",
2177 __func__, tlv_length, length);
2178 }
2179 }
2180
2181 while (length >= 4) {
2182 uint16_t subtype = 0;
2183 uint16_t sublength = 0;
2184 struct bgp_attr_encap_subtlv *tlv;
2185
2186 if (BGP_ATTR_ENCAP == type) {
2187 subtype = stream_getc (BGP_INPUT (peer));
2188 sublength = stream_getc (BGP_INPUT (peer));
2189 length -= 2;
2190 #if ENABLE_BGP_VNC
2191 } else {
2192 subtype = stream_getw (BGP_INPUT (peer));
2193 sublength = stream_getw (BGP_INPUT (peer));
2194 length -= 4;
2195 #endif
2196 }
2197
2198 if (sublength > length) {
2199 zlog_info ("Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
2200 sublength, length);
2201 bgp_notify_send_with_data (peer,
2202 BGP_NOTIFY_UPDATE_ERR,
2203 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2204 startp, total);
2205 return -1;
2206 }
2207
2208 /* alloc and copy sub-tlv */
2209 /* TBD make sure these are freed when attributes are released */
2210 tlv = XCALLOC (MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv)-1+sublength);
2211 tlv->type = subtype;
2212 tlv->length = sublength;
2213 stream_get(tlv->value, peer->ibuf, sublength);
2214 length -= sublength;
2215
2216 /* attach tlv to encap chain */
2217 if (!attre) {
2218 attre = bgp_attr_extra_get(attr);
2219 if (BGP_ATTR_ENCAP == type) {
2220 for (stlv_last = attre->encap_subtlvs; stlv_last && stlv_last->next;
2221 stlv_last = stlv_last->next);
2222 if (stlv_last) {
2223 stlv_last->next = tlv;
2224 } else {
2225 attre->encap_subtlvs = tlv;
2226 }
2227 #if ENABLE_BGP_VNC
2228 } else {
2229 for (stlv_last = attre->vnc_subtlvs; stlv_last && stlv_last->next;
2230 stlv_last = stlv_last->next);
2231 if (stlv_last) {
2232 stlv_last->next = tlv;
2233 } else {
2234 attre->vnc_subtlvs = tlv;
2235 }
2236 #endif
2237 }
2238 } else {
2239 stlv_last->next = tlv;
2240 }
2241 stlv_last = tlv;
2242 }
2243
2244 if (BGP_ATTR_ENCAP == type) {
2245 if (!attre)
2246 attre = bgp_attr_extra_get(attr);
2247 attre->encap_tunneltype = tunneltype;
2248 }
2249
2250 if (length) {
2251 /* spurious leftover data */
2252 zlog_info ("Tunnel Encap attribute length is bad: %d leftover octets", length);
2253 bgp_notify_send_with_data (peer,
2254 BGP_NOTIFY_UPDATE_ERR,
2255 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2256 startp, total);
2257 return -1;
2258 }
2259
2260 return 0;
2261 }
2262
2263 /* Prefix SID attribute
2264 * draft-ietf-idr-bgp-prefix-sid-05
2265 */
2266 static bgp_attr_parse_ret_t
2267 bgp_attr_prefix_sid (struct bgp_attr_parser_args *args, struct bgp_nlri *mp_update)
2268 {
2269 struct peer *const peer = args->peer;
2270 struct attr *const attr = args->attr;
2271 int type;
2272 int length;
2273 u_int32_t label_index;
2274 struct in6_addr ipv6_sid;
2275 u_int32_t srgb_base;
2276 u_int32_t srgb_range;
2277 int srgb_count;
2278
2279 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID);
2280
2281 type = stream_getc (peer->ibuf);
2282 length = stream_getw (peer->ibuf);
2283
2284 if (type == BGP_PREFIX_SID_LABEL_INDEX)
2285 {
2286 if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH)
2287 {
2288 zlog_err ("Prefix SID label index length is %d instead of %d", length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
2289 return bgp_attr_malformed (args,
2290 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2291 args->total);
2292 }
2293
2294 /* Ignore flags and reserved */
2295 stream_getc (peer->ibuf);
2296 stream_getw (peer->ibuf);
2297
2298 /* Fetch the label index and see if it is valid. */
2299 label_index = stream_getl (peer->ibuf);
2300 if (label_index == BGP_INVALID_LABEL_INDEX)
2301 return bgp_attr_malformed (args,
2302 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2303 args->total);
2304
2305 /* Store label index; subsequently, we'll check on address-family */
2306 (bgp_attr_extra_get (attr))->label_index = label_index;
2307
2308 /*
2309 * Ignore the Label index attribute unless received for labeled-unicast
2310 * SAFI.
2311 */
2312 if (!mp_update->length || mp_update->safi != SAFI_LABELED_UNICAST)
2313 attr->extra->label_index = BGP_INVALID_LABEL_INDEX;
2314 }
2315
2316 /* Placeholder code for the IPv6 SID type */
2317 else if (type == BGP_PREFIX_SID_IPV6)
2318 {
2319 if (length != BGP_PREFIX_SID_IPV6_LENGTH)
2320 {
2321 zlog_err ("Prefix SID IPv6 length is %d instead of %d", length, BGP_PREFIX_SID_IPV6_LENGTH);
2322 return bgp_attr_malformed (args,
2323 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2324 args->total);
2325 }
2326
2327 /* Ignore reserved */
2328 stream_getc (peer->ibuf);
2329 stream_getw (peer->ibuf);
2330
2331 stream_get (&ipv6_sid, peer->ibuf, 16);
2332 }
2333
2334 /* Placeholder code for the Originator SRGB type */
2335 else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB)
2336 {
2337 /* Ignore flags */
2338 stream_getw (peer->ibuf);
2339
2340 length -= 2;
2341
2342 if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH)
2343 {
2344 zlog_err ("Prefix SID Originator SRGB length is %d, it must be a multiple of %d ",
2345 length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
2346 return bgp_attr_malformed (args,
2347 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2348 args->total);
2349 }
2350
2351 srgb_count = length / BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH;
2352
2353 for (int i = 0; i < srgb_count; i++)
2354 {
2355 stream_get (&srgb_base, peer->ibuf, 3);
2356 stream_get (&srgb_range, peer->ibuf, 3);
2357 }
2358 }
2359
2360 return BGP_ATTR_PARSE_PROCEED;
2361 }
2362
2363 /* BGP unknown attribute treatment. */
2364 static bgp_attr_parse_ret_t
2365 bgp_attr_unknown (struct bgp_attr_parser_args *args)
2366 {
2367 bgp_size_t total = args->total;
2368 struct transit *transit;
2369 struct attr_extra *attre;
2370 struct peer *const peer = args->peer;
2371 struct attr *const attr = args->attr;
2372 u_char *const startp = args->startp;
2373 const u_char type = args->type;
2374 const u_char flag = args->flags;
2375 const bgp_size_t length = args->length;
2376
2377 if (bgp_debug_update(peer, NULL, NULL, 1))
2378 zlog_debug ("%s Unknown attribute is received (type %d, length %d)",
2379 peer->host, type, length);
2380
2381 /* Forward read pointer of input stream. */
2382 stream_forward_getp (peer->ibuf, length);
2383
2384 /* If any of the mandatory well-known attributes are not recognized,
2385 then the Error Subcode is set to Unrecognized Well-known
2386 Attribute. The Data field contains the unrecognized attribute
2387 (type, length and value). */
2388 if (!CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
2389 {
2390 return bgp_attr_malformed (args,
2391 BGP_NOTIFY_UPDATE_UNREC_ATTR,
2392 args->total);
2393 }
2394
2395 /* Unrecognized non-transitive optional attributes must be quietly
2396 ignored and not passed along to other BGP peers. */
2397 if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
2398 return BGP_ATTR_PARSE_PROCEED;
2399
2400 /* If a path with recognized transitive optional attribute is
2401 accepted and passed along to other BGP peers and the Partial bit
2402 in the Attribute Flags octet is set to 1 by some previous AS, it
2403 is not set back to 0 by the current AS. */
2404 SET_FLAG (*startp, BGP_ATTR_FLAG_PARTIAL);
2405
2406 /* Store transitive attribute to the end of attr->transit. */
2407 if (! ((attre = bgp_attr_extra_get(attr))->transit) )
2408 attre->transit = XCALLOC (MTYPE_TRANSIT, sizeof (struct transit));
2409
2410 transit = attre->transit;
2411
2412 if (transit->val)
2413 transit->val = XREALLOC (MTYPE_TRANSIT_VAL, transit->val,
2414 transit->length + total);
2415 else
2416 transit->val = XMALLOC (MTYPE_TRANSIT_VAL, total);
2417
2418 memcpy (transit->val + transit->length, startp, total);
2419 transit->length += total;
2420
2421 return BGP_ATTR_PARSE_PROCEED;
2422 }
2423
2424 /* Well-known attribute check. */
2425 static int
2426 bgp_attr_check (struct peer *peer, struct attr *attr)
2427 {
2428 u_char type = 0;
2429
2430 /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an
2431 * empty UPDATE. */
2432 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag)
2433 return BGP_ATTR_PARSE_PROCEED;
2434
2435 /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required
2436 to carry any other path attributes.", though if MP_REACH_NLRI or NLRI
2437 are present, it should. Check for any other attribute being present
2438 instead.
2439 */
2440 if (attr->flag == ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI))
2441 return BGP_ATTR_PARSE_PROCEED;
2442
2443 if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_ORIGIN)))
2444 type = BGP_ATTR_ORIGIN;
2445
2446 if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH)))
2447 type = BGP_ATTR_AS_PATH;
2448
2449 /* RFC 2858 makes Next-Hop optional/ignored, if MP_REACH_NLRI is present and
2450 * NLRI is empty. We can't easily check NLRI empty here though.
2451 */
2452 if (!CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))
2453 && !CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_MP_REACH_NLRI)))
2454 type = BGP_ATTR_NEXT_HOP;
2455
2456 if (peer->sort == BGP_PEER_IBGP
2457 && ! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
2458 type = BGP_ATTR_LOCAL_PREF;
2459
2460 if (type)
2461 {
2462 zlog_warn ("%s Missing well-known attribute %s.", peer->host,
2463 LOOKUP (attr_str, type));
2464 bgp_notify_send_with_data (peer,
2465 BGP_NOTIFY_UPDATE_ERR,
2466 BGP_NOTIFY_UPDATE_MISS_ATTR,
2467 &type, 1);
2468 return BGP_ATTR_PARSE_ERROR;
2469 }
2470 return BGP_ATTR_PARSE_PROCEED;
2471 }
2472
2473 /* Read attribute of update packet. This function is called from
2474 bgp_update_receive() in bgp_packet.c. */
2475 bgp_attr_parse_ret_t
2476 bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
2477 struct bgp_nlri *mp_update, struct bgp_nlri *mp_withdraw)
2478 {
2479 int ret;
2480 u_char flag = 0;
2481 u_char type = 0;
2482 bgp_size_t length;
2483 u_char *startp, *endp;
2484 u_char *attr_endp;
2485 u_char seen[BGP_ATTR_BITMAP_SIZE];
2486 /* we need the as4_path only until we have synthesized the as_path with it */
2487 /* same goes for as4_aggregator */
2488 struct aspath *as4_path = NULL;
2489 as_t as4_aggregator = 0;
2490 struct in_addr as4_aggregator_addr = { .s_addr = 0 };
2491
2492 /* Initialize bitmap. */
2493 memset (seen, 0, BGP_ATTR_BITMAP_SIZE);
2494
2495 /* End pointer of BGP attribute. */
2496 endp = BGP_INPUT_PNT (peer) + size;
2497
2498 /* Get attributes to the end of attribute length. */
2499 while (BGP_INPUT_PNT (peer) < endp)
2500 {
2501 /* Check remaining length check.*/
2502 if (endp - BGP_INPUT_PNT (peer) < BGP_ATTR_MIN_LEN)
2503 {
2504 /* XXX warning: long int format, int arg (arg 5) */
2505 zlog_warn ("%s: error BGP attribute length %lu is smaller than min len",
2506 peer->host,
2507 (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
2508
2509 bgp_notify_send (peer,
2510 BGP_NOTIFY_UPDATE_ERR,
2511 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
2512 return BGP_ATTR_PARSE_ERROR;
2513 }
2514
2515 /* Fetch attribute flag and type. */
2516 startp = BGP_INPUT_PNT (peer);
2517 /* "The lower-order four bits of the Attribute Flags octet are
2518 unused. They MUST be zero when sent and MUST be ignored when
2519 received." */
2520 flag = 0xF0 & stream_getc (BGP_INPUT (peer));
2521 type = stream_getc (BGP_INPUT (peer));
2522
2523 /* Check whether Extended-Length applies and is in bounds */
2524 if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN)
2525 && ((endp - startp) < (BGP_ATTR_MIN_LEN + 1)))
2526 {
2527 zlog_warn ("%s: Extended length set, but just %lu bytes of attr header",
2528 peer->host,
2529 (unsigned long) (endp - STREAM_PNT (BGP_INPUT (peer))));
2530
2531 bgp_notify_send (peer,
2532 BGP_NOTIFY_UPDATE_ERR,
2533 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
2534 return BGP_ATTR_PARSE_ERROR;
2535 }
2536
2537 /* Check extended attribue length bit. */
2538 if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN))
2539 length = stream_getw (BGP_INPUT (peer));
2540 else
2541 length = stream_getc (BGP_INPUT (peer));
2542
2543 /* If any attribute appears more than once in the UPDATE
2544 message, then the Error Subcode is set to Malformed Attribute
2545 List. */
2546
2547 if (CHECK_BITMAP (seen, type))
2548 {
2549 zlog_warn ("%s: error BGP attribute type %d appears twice in a message",
2550 peer->host, type);
2551
2552 bgp_notify_send (peer,
2553 BGP_NOTIFY_UPDATE_ERR,
2554 BGP_NOTIFY_UPDATE_MAL_ATTR);
2555 return BGP_ATTR_PARSE_ERROR;
2556 }
2557
2558 /* Set type to bitmap to check duplicate attribute. `type' is
2559 unsigned char so it never overflow bitmap range. */
2560
2561 SET_BITMAP (seen, type);
2562
2563 /* Overflow check. */
2564 attr_endp = BGP_INPUT_PNT (peer) + length;
2565
2566 if (attr_endp > endp)
2567 {
2568 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);
2569 bgp_notify_send_with_data (peer,
2570 BGP_NOTIFY_UPDATE_ERR,
2571 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2572 startp, attr_endp - startp);
2573 return BGP_ATTR_PARSE_ERROR;
2574 }
2575
2576 struct bgp_attr_parser_args attr_args = {
2577 .peer = peer,
2578 .length = length,
2579 .attr = attr,
2580 .type = type,
2581 .flags = flag,
2582 .startp = startp,
2583 .total = attr_endp - startp,
2584 };
2585
2586
2587 /* If any recognized attribute has Attribute Flags that conflict
2588 with the Attribute Type Code, then the Error Subcode is set to
2589 Attribute Flags Error. The Data field contains the erroneous
2590 attribute (type, length and value). */
2591 if (bgp_attr_flag_invalid (&attr_args))
2592 {
2593 bgp_attr_parse_ret_t ret;
2594 ret = bgp_attr_malformed (&attr_args,
2595 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
2596 attr_args.total);
2597 if (ret == BGP_ATTR_PARSE_PROCEED)
2598 continue;
2599 return ret;
2600 }
2601
2602 /* OK check attribute and store it's value. */
2603 switch (type)
2604 {
2605 case BGP_ATTR_ORIGIN:
2606 ret = bgp_attr_origin (&attr_args);
2607 break;
2608 case BGP_ATTR_AS_PATH:
2609 ret = bgp_attr_aspath (&attr_args);
2610 break;
2611 case BGP_ATTR_AS4_PATH:
2612 ret = bgp_attr_as4_path (&attr_args, &as4_path);
2613 break;
2614 case BGP_ATTR_NEXT_HOP:
2615 ret = bgp_attr_nexthop (&attr_args);
2616 break;
2617 case BGP_ATTR_MULTI_EXIT_DISC:
2618 ret = bgp_attr_med (&attr_args);
2619 break;
2620 case BGP_ATTR_LOCAL_PREF:
2621 ret = bgp_attr_local_pref (&attr_args);
2622 break;
2623 case BGP_ATTR_ATOMIC_AGGREGATE:
2624 ret = bgp_attr_atomic (&attr_args);
2625 break;
2626 case BGP_ATTR_AGGREGATOR:
2627 ret = bgp_attr_aggregator (&attr_args);
2628 break;
2629 case BGP_ATTR_AS4_AGGREGATOR:
2630 ret = bgp_attr_as4_aggregator (&attr_args,
2631 &as4_aggregator,
2632 &as4_aggregator_addr);
2633 break;
2634 case BGP_ATTR_COMMUNITIES:
2635 ret = bgp_attr_community (&attr_args);
2636 break;
2637 case BGP_ATTR_LARGE_COMMUNITIES:
2638 ret = bgp_attr_large_community (&attr_args);
2639 break;
2640 case BGP_ATTR_ORIGINATOR_ID:
2641 ret = bgp_attr_originator_id (&attr_args);
2642 break;
2643 case BGP_ATTR_CLUSTER_LIST:
2644 ret = bgp_attr_cluster_list (&attr_args);
2645 break;
2646 case BGP_ATTR_MP_REACH_NLRI:
2647 ret = bgp_mp_reach_parse (&attr_args, mp_update);
2648 break;
2649 case BGP_ATTR_MP_UNREACH_NLRI:
2650 ret = bgp_mp_unreach_parse (&attr_args, mp_withdraw);
2651 break;
2652 case BGP_ATTR_EXT_COMMUNITIES:
2653 ret = bgp_attr_ext_communities (&attr_args);
2654 break;
2655 #if ENABLE_BGP_VNC
2656 case BGP_ATTR_VNC:
2657 #endif
2658 case BGP_ATTR_ENCAP:
2659 ret = bgp_attr_encap (type, peer, length, attr, flag, startp);
2660 break;
2661 case BGP_ATTR_PREFIX_SID:
2662 ret = bgp_attr_prefix_sid (&attr_args, mp_update);
2663 break;
2664 default:
2665 ret = bgp_attr_unknown (&attr_args);
2666 break;
2667 }
2668
2669 if (ret == BGP_ATTR_PARSE_ERROR_NOTIFYPLS)
2670 {
2671 bgp_notify_send (peer,
2672 BGP_NOTIFY_UPDATE_ERR,
2673 BGP_NOTIFY_UPDATE_MAL_ATTR);
2674 ret = BGP_ATTR_PARSE_ERROR;
2675 }
2676
2677 /* If hard error occured immediately return to the caller. */
2678 if (ret == BGP_ATTR_PARSE_ERROR)
2679 {
2680 zlog_warn ("%s: Attribute %s, parse error",
2681 peer->host,
2682 LOOKUP (attr_str, type));
2683 if (as4_path)
2684 aspath_unintern (&as4_path);
2685 return ret;
2686 }
2687 if (ret == BGP_ATTR_PARSE_WITHDRAW)
2688 {
2689
2690 zlog_warn ("%s: Attribute %s, parse error - treating as withdrawal",
2691 peer->host,
2692 LOOKUP (attr_str, type));
2693 if (as4_path)
2694 aspath_unintern (&as4_path);
2695 return ret;
2696 }
2697
2698 /* Check the fetched length. */
2699 if (BGP_INPUT_PNT (peer) != attr_endp)
2700 {
2701 zlog_warn ("%s: BGP attribute %s, fetch error",
2702 peer->host, LOOKUP (attr_str, type));
2703 bgp_notify_send (peer,
2704 BGP_NOTIFY_UPDATE_ERR,
2705 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
2706 if (as4_path)
2707 aspath_unintern (&as4_path);
2708 return BGP_ATTR_PARSE_ERROR;
2709 }
2710 }
2711
2712 /* Check final read pointer is same as end pointer. */
2713 if (BGP_INPUT_PNT (peer) != endp)
2714 {
2715 zlog_warn ("%s: BGP attribute %s, length mismatch",
2716 peer->host, LOOKUP (attr_str, type));
2717 bgp_notify_send (peer,
2718 BGP_NOTIFY_UPDATE_ERR,
2719 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
2720 if (as4_path)
2721 aspath_unintern (&as4_path);
2722 return BGP_ATTR_PARSE_ERROR;
2723 }
2724
2725 /* Check all mandatory well-known attributes are present */
2726 {
2727 bgp_attr_parse_ret_t ret;
2728 if ((ret = bgp_attr_check (peer, attr)) < 0)
2729 {
2730 if (as4_path)
2731 aspath_unintern (&as4_path);
2732 return ret;
2733 }
2734 }
2735
2736 /*
2737 * At this place we can see whether we got AS4_PATH and/or
2738 * AS4_AGGREGATOR from a 16Bit peer and act accordingly.
2739 * We can not do this before we've read all attributes because
2740 * the as4 handling does not say whether AS4_PATH has to be sent
2741 * after AS_PATH or not - and when AS4_AGGREGATOR will be send
2742 * in relationship to AGGREGATOR.
2743 * So, to be defensive, we are not relying on any order and read
2744 * all attributes first, including these 32bit ones, and now,
2745 * afterwards, we look what and if something is to be done for as4.
2746 *
2747 * It is possible to not have AS_PATH, e.g. GR EoR and sole
2748 * MP_UNREACH_NLRI.
2749 */
2750 /* actually... this doesn't ever return failure currently, but
2751 * better safe than sorry */
2752 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH))
2753 && bgp_attr_munge_as4_attrs (peer, attr, as4_path,
2754 as4_aggregator, &as4_aggregator_addr))
2755 {
2756 bgp_notify_send (peer,
2757 BGP_NOTIFY_UPDATE_ERR,
2758 BGP_NOTIFY_UPDATE_MAL_ATTR);
2759 if (as4_path)
2760 aspath_unintern (&as4_path);
2761 return BGP_ATTR_PARSE_ERROR;
2762 }
2763
2764 /* At this stage, we have done all fiddling with as4, and the
2765 * resulting info is in attr->aggregator resp. attr->aspath
2766 * so we can chuck as4_aggregator and as4_path alltogether in
2767 * order to save memory
2768 */
2769 if (as4_path)
2770 {
2771 aspath_unintern (&as4_path); /* unintern - it is in the hash */
2772 /* The flag that we got this is still there, but that does not
2773 * do any trouble
2774 */
2775 }
2776 /*
2777 * The "rest" of the code does nothing with as4_aggregator.
2778 * there is no memory attached specifically which is not part
2779 * of the attr.
2780 * so ignoring just means do nothing.
2781 */
2782 /*
2783 * Finally do the checks on the aspath we did not do yet
2784 * because we waited for a potentially synthesized aspath.
2785 */
2786 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))
2787 {
2788 ret = bgp_attr_aspath_check (peer, attr);
2789 if (ret != BGP_ATTR_PARSE_PROCEED)
2790 return ret;
2791 }
2792 if (attr->extra)
2793 {
2794 /* Finally intern unknown attribute. */
2795 if (attr->extra->transit)
2796 attr->extra->transit = transit_intern (attr->extra->transit);
2797 if (attr->extra->encap_subtlvs)
2798 attr->extra->encap_subtlvs = encap_intern (attr->extra->encap_subtlvs, ENCAP_SUBTLV_TYPE);
2799 #if ENABLE_BGP_VNC
2800 if (attr->extra->vnc_subtlvs)
2801 attr->extra->vnc_subtlvs = encap_intern (attr->extra->vnc_subtlvs, VNC_SUBTLV_TYPE);
2802 #endif
2803 }
2804
2805 return BGP_ATTR_PARSE_PROCEED;
2806 }
2807
2808 size_t
2809 bgp_packet_mpattr_start (struct stream *s, struct peer *peer,
2810 afi_t afi, safi_t safi,
2811 struct bpacket_attr_vec_arr *vecarr,
2812 struct attr *attr)
2813 {
2814 size_t sizep;
2815 iana_afi_t pkt_afi;
2816 safi_t pkt_safi;
2817 afi_t nh_afi;
2818
2819 /* Set extended bit always to encode the attribute length as 2 bytes */
2820 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
2821 stream_putc (s, BGP_ATTR_MP_REACH_NLRI);
2822 sizep = stream_get_endp (s);
2823 stream_putw (s, 0); /* Marker: Attribute length. */
2824
2825
2826 /* Convert AFI, SAFI to values for packet. */
2827 bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
2828
2829 stream_putw (s, pkt_afi); /* AFI */
2830 stream_putc (s, pkt_safi); /* SAFI */
2831
2832 /* Nexthop AFI */
2833 if (peer_cap_enhe(peer, afi, safi)) {
2834 nh_afi = AFI_IP6;
2835 } else {
2836 if (afi == AFI_L2VPN)
2837 nh_afi = AFI_L2VPN;
2838 else if (safi == SAFI_LABELED_UNICAST)
2839 nh_afi = afi;
2840 else
2841 nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
2842 }
2843
2844 /* Nexthop */
2845 switch (nh_afi)
2846 {
2847 case AFI_IP:
2848 switch (safi)
2849 {
2850 case SAFI_UNICAST:
2851 case SAFI_MULTICAST:
2852 case SAFI_LABELED_UNICAST:
2853 bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
2854 stream_putc (s, 4);
2855 stream_put_ipv4 (s, attr->nexthop.s_addr);
2856 break;
2857 case SAFI_MPLS_VPN:
2858 bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
2859 stream_putc (s, 12);
2860 stream_putl (s, 0); /* RD = 0, per RFC */
2861 stream_putl (s, 0);
2862 stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
2863 break;
2864 case SAFI_ENCAP:
2865 stream_putc (s, 4);
2866 stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
2867 break;
2868 default:
2869 break;
2870 }
2871 break;
2872 case AFI_IP6:
2873 switch (safi)
2874 {
2875 case SAFI_UNICAST:
2876 case SAFI_MULTICAST:
2877 case SAFI_LABELED_UNICAST:
2878 {
2879 struct attr_extra *attre = attr->extra;
2880
2881 assert (attr->extra);
2882 bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
2883
2884 if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
2885 stream_putc (s, BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL);
2886 stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
2887 stream_put (s, &attre->mp_nexthop_local, IPV6_MAX_BYTELEN);
2888 } else {
2889 stream_putc (s, IPV6_MAX_BYTELEN);
2890 stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
2891 }
2892 }
2893 break;
2894 case SAFI_MPLS_VPN:
2895 {
2896 struct attr_extra *attre = attr->extra;
2897
2898 assert (attr->extra);
2899 if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
2900 stream_putc (s, 24);
2901 stream_putl (s, 0); /* RD = 0, per RFC */
2902 stream_putl (s, 0);
2903 stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
2904 } else if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
2905 stream_putc (s, 48);
2906 stream_putl (s, 0); /* RD = 0, per RFC */
2907 stream_putl (s, 0);
2908 stream_put (s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
2909 stream_putl (s, 0); /* RD = 0, per RFC */
2910 stream_putl (s, 0);
2911 stream_put (s, &attre->mp_nexthop_local, IPV6_MAX_BYTELEN);
2912 }
2913 }
2914 break;
2915 case SAFI_ENCAP:
2916 assert (attr->extra);
2917 stream_putc (s, IPV6_MAX_BYTELEN);
2918 stream_put (s, &attr->extra->mp_nexthop_global, IPV6_MAX_BYTELEN);
2919 break;
2920 default:
2921 break;
2922 }
2923 break;
2924 case AFI_L2VPN:
2925 switch (safi)
2926 {
2927 case SAFI_EVPN:
2928 if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV4)
2929 {
2930 stream_putc (s, 12);
2931 stream_putl (s, 0); /* RD = 0, per RFC */
2932 stream_putl (s, 0);
2933 stream_put (s, &attr->extra->mp_nexthop_global_in, 4);
2934 }
2935 else if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL)
2936 {
2937 stream_putc (s, 24);
2938 stream_putl (s, 0); /* RD = 0, per RFC */
2939 stream_putl (s, 0);
2940 stream_put (s, &attr->extra->mp_nexthop_global, IPV6_MAX_BYTELEN);
2941 }
2942 else if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
2943 {
2944 stream_putc (s, 48);
2945 stream_putl (s, 0); /* RD = 0, per RFC */
2946 stream_putl (s, 0);
2947 stream_put (s, &attr->extra->mp_nexthop_global, IPV6_MAX_BYTELEN);
2948 stream_putl (s, 0); /* RD = 0, per RFC */
2949 stream_putl (s, 0);
2950 stream_put (s, &attr->extra->mp_nexthop_local, IPV6_MAX_BYTELEN);
2951 }
2952 break;
2953 break;
2954 default:
2955 break;
2956 }
2957 default:
2958 break;
2959 }
2960
2961 /* SNPA */
2962 stream_putc (s, 0);
2963 return sizep;
2964 }
2965
2966 void
2967 bgp_packet_mpattr_prefix (struct stream *s, afi_t afi, safi_t safi,
2968 struct prefix *p, struct prefix_rd *prd,
2969 u_char *tag, int addpath_encode,
2970 u_int32_t addpath_tx_id, struct attr *attr)
2971 {
2972 if (safi == SAFI_MPLS_VPN)
2973 {
2974 if (addpath_encode)
2975 stream_putl(s, addpath_tx_id);
2976 /* Tag, RD, Prefix write. */
2977 stream_putc (s, p->prefixlen + 88);
2978 stream_put (s, tag, 3);
2979 stream_put (s, prd->val, 8);
2980 stream_put (s, &p->u.prefix, PSIZE (p->prefixlen));
2981 }
2982 else if (safi == SAFI_EVPN)
2983 {
2984 bgp_packet_mpattr_route_type_5(s, p, prd, tag, attr);
2985 }
2986 else if (safi == SAFI_LABELED_UNICAST)
2987 {
2988 /* Prefix write with label. */
2989 stream_put_labeled_prefix(s, p, tag);
2990 }
2991 else
2992 stream_put_prefix_addpath (s, p, addpath_encode, addpath_tx_id);
2993 }
2994
2995 size_t
2996 bgp_packet_mpattr_prefix_size (afi_t afi, safi_t safi, struct prefix *p)
2997 {
2998 int size = PSIZE (p->prefixlen);
2999 if (safi == SAFI_MPLS_VPN)
3000 size += 88;
3001 return size;
3002 }
3003
3004 /*
3005 * Encodes the tunnel encapsulation attribute,
3006 * and with ENABLE_BGP_VNC the VNC attribute which uses
3007 * almost the same TLV format
3008 */
3009 static void
3010 bgp_packet_mpattr_tea(
3011 struct bgp *bgp,
3012 struct peer *peer,
3013 struct stream *s,
3014 struct attr *attr,
3015 uint8_t attrtype)
3016 {
3017 unsigned int attrlenfield = 0;
3018 unsigned int attrhdrlen = 0;
3019 struct bgp_attr_encap_subtlv *subtlvs;
3020 struct bgp_attr_encap_subtlv *st;
3021 const char *attrname;
3022
3023 if (!attr || !attr->extra ||
3024 (attrtype == BGP_ATTR_ENCAP &&
3025 (!attr->extra->encap_tunneltype ||
3026 attr->extra->encap_tunneltype == BGP_ENCAP_TYPE_MPLS)))
3027 return;
3028
3029 switch (attrtype) {
3030 case BGP_ATTR_ENCAP:
3031 attrname = "Tunnel Encap";
3032 subtlvs = attr->extra->encap_subtlvs;
3033
3034 /*
3035 * The tunnel encap attr has an "outer" tlv.
3036 * T = tunneltype,
3037 * L = total length of subtlvs,
3038 * V = concatenated subtlvs.
3039 */
3040 attrlenfield = 2 + 2; /* T + L */
3041 attrhdrlen = 1 + 1; /* subTLV T + L */
3042 break;
3043
3044 #if ENABLE_BGP_VNC
3045 case BGP_ATTR_VNC:
3046 attrname = "VNC";
3047 subtlvs = attr->extra->vnc_subtlvs;
3048 attrlenfield = 0; /* no outer T + L */
3049 attrhdrlen = 2 + 2; /* subTLV T + L */
3050 break;
3051 #endif
3052
3053 default:
3054 assert(0);
3055 }
3056
3057 /* compute attr length */
3058 for (st = subtlvs; st; st = st->next) {
3059 attrlenfield += (attrhdrlen + st->length);
3060 }
3061
3062 if (attrlenfield > 0xffff) {
3063 zlog_info ("%s attribute is too long (length=%d), can't send it",
3064 attrname,
3065 attrlenfield);
3066 return;
3067 }
3068
3069 if (attrlenfield > 0xff) {
3070 /* 2-octet length field */
3071 stream_putc (s,
3072 BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
3073 stream_putc (s, attrtype);
3074 stream_putw (s, attrlenfield & 0xffff);
3075 } else {
3076 /* 1-octet length field */
3077 stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL);
3078 stream_putc (s, attrtype);
3079 stream_putc (s, attrlenfield & 0xff);
3080 }
3081
3082 if (attrtype == BGP_ATTR_ENCAP) {
3083 /* write outer T+L */
3084 stream_putw(s, attr->extra->encap_tunneltype);
3085 stream_putw(s, attrlenfield - 4);
3086 }
3087
3088 /* write each sub-tlv */
3089 for (st = subtlvs; st; st = st->next) {
3090 if (attrtype == BGP_ATTR_ENCAP) {
3091 stream_putc (s, st->type);
3092 stream_putc (s, st->length);
3093 #if ENABLE_BGP_VNC
3094 } else {
3095 stream_putw (s, st->type);
3096 stream_putw (s, st->length);
3097 #endif
3098 }
3099 stream_put (s, st->value, st->length);
3100 }
3101 }
3102
3103 void
3104 bgp_packet_mpattr_end (struct stream *s, size_t sizep)
3105 {
3106 /* Set MP attribute length. Don't count the (2) bytes used to encode
3107 the attr length */
3108 stream_putw_at (s, sizep, (stream_get_endp (s) - sizep) - 2);
3109 }
3110
3111 /* Make attribute packet. */
3112 bgp_size_t
3113 bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
3114 struct stream *s, struct attr *attr,
3115 struct bpacket_attr_vec_arr *vecarr,
3116 struct prefix *p, afi_t afi, safi_t safi,
3117 struct peer *from, struct prefix_rd *prd, u_char *tag,
3118 int addpath_encode,
3119 u_int32_t addpath_tx_id)
3120 {
3121 size_t cp;
3122 size_t aspath_sizep;
3123 struct aspath *aspath;
3124 int send_as4_path = 0;
3125 int send_as4_aggregator = 0;
3126 int use32bit = (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0;
3127
3128 if (! bgp)
3129 bgp = peer->bgp;
3130
3131 /* Remember current pointer. */
3132 cp = stream_get_endp (s);
3133
3134 if (p && !((afi == AFI_IP && safi == SAFI_UNICAST) &&
3135 !peer_cap_enhe(peer, afi, safi)))
3136 {
3137 size_t mpattrlen_pos = 0;
3138
3139 mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi, vecarr, attr);
3140 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag,
3141 addpath_encode, addpath_tx_id, attr);
3142 bgp_packet_mpattr_end(s, mpattrlen_pos);
3143 }
3144
3145 /* Origin attribute. */
3146 stream_putc (s, BGP_ATTR_FLAG_TRANS);
3147 stream_putc (s, BGP_ATTR_ORIGIN);
3148 stream_putc (s, 1);
3149 stream_putc (s, attr->origin);
3150
3151 /* AS path attribute. */
3152
3153 /* If remote-peer is EBGP */
3154 if (peer->sort == BGP_PEER_EBGP
3155 && (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
3156 || attr->aspath->segments == NULL)
3157 && (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)))
3158 {
3159 aspath = aspath_dup (attr->aspath);
3160
3161 /* Even though we may not be configured for confederations we may have
3162 * RXed an AS_PATH with AS_CONFED_SEQUENCE or AS_CONFED_SET */
3163 aspath = aspath_delete_confed_seq (aspath);
3164
3165 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
3166 {
3167 /* Stuff our path CONFED_ID on the front */
3168 aspath = aspath_add_seq (aspath, bgp->confed_id);
3169 }
3170 else
3171 {
3172 if (peer->change_local_as) {
3173 /* If replace-as is specified, we only use the change_local_as when
3174 advertising routes. */
3175 if( ! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ) {
3176 aspath = aspath_add_seq (aspath, peer->local_as);
3177 }
3178 aspath = aspath_add_seq (aspath, peer->change_local_as);
3179 } else {
3180 aspath = aspath_add_seq (aspath, peer->local_as);
3181 }
3182 }
3183 }
3184 else if (peer->sort == BGP_PEER_CONFED)
3185 {
3186 /* A confed member, so we need to do the AS_CONFED_SEQUENCE thing */
3187 aspath = aspath_dup (attr->aspath);
3188 aspath = aspath_add_confed_seq (aspath, peer->local_as);
3189 }
3190 else
3191 aspath = attr->aspath;
3192
3193 /* If peer is not AS4 capable, then:
3194 * - send the created AS_PATH out as AS4_PATH (optional, transitive),
3195 * but ensure that no AS_CONFED_SEQUENCE and AS_CONFED_SET path segment
3196 * types are in it (i.e. exclude them if they are there)
3197 * AND do this only if there is at least one asnum > 65535 in the path!
3198 * - send an AS_PATH out, but put 16Bit ASnums in it, not 32bit, and change
3199 * all ASnums > 65535 to BGP_AS_TRANS
3200 */
3201
3202 stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3203 stream_putc (s, BGP_ATTR_AS_PATH);
3204 aspath_sizep = stream_get_endp (s);
3205 stream_putw (s, 0);
3206 stream_putw_at (s, aspath_sizep, aspath_put (s, aspath, use32bit));
3207
3208 /* OLD session may need NEW_AS_PATH sent, if there are 4-byte ASNs
3209 * in the path
3210 */
3211 if (!use32bit && aspath_has_as4 (aspath))
3212 send_as4_path = 1; /* we'll do this later, at the correct place */
3213
3214 /* Nexthop attribute. */
3215 if (afi == AFI_IP && safi == SAFI_UNICAST && !peer_cap_enhe(peer, afi, safi))
3216 {
3217 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))
3218 {
3219 stream_putc (s, BGP_ATTR_FLAG_TRANS);
3220 stream_putc (s, BGP_ATTR_NEXT_HOP);
3221 bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, attr);
3222 stream_putc (s, 4);
3223 stream_put_ipv4 (s, attr->nexthop.s_addr);
3224 }
3225 else if (peer_cap_enhe(from, afi, safi))
3226 {
3227 /*
3228 * Likely this is the case when an IPv4 prefix was received with
3229 * Extended Next-hop capability and now being advertised to
3230 * non-ENHE peers.
3231 * Setting the mandatory (ipv4) next-hop attribute here to enable
3232 * implicit next-hop self with correct (ipv4 address family).
3233 */
3234 stream_putc (s, BGP_ATTR_FLAG_TRANS);
3235 stream_putc (s, BGP_ATTR_NEXT_HOP);
3236 bpacket_attr_vec_arr_set_vec (vecarr, BGP_ATTR_VEC_NH, s, NULL);
3237 stream_putc (s, 4);
3238 stream_put_ipv4 (s, 0);
3239 }
3240 }
3241
3242 /* MED attribute. */
3243 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC) ||
3244 bgp->maxmed_active)
3245 {
3246 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
3247 stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC);
3248 stream_putc (s, 4);
3249 stream_putl (s, (bgp->maxmed_active ? bgp->maxmed_value : attr->med));
3250 }
3251
3252 /* Local preference. */
3253 if (peer->sort == BGP_PEER_IBGP ||
3254 peer->sort == BGP_PEER_CONFED)
3255 {
3256 stream_putc (s, BGP_ATTR_FLAG_TRANS);
3257 stream_putc (s, BGP_ATTR_LOCAL_PREF);
3258 stream_putc (s, 4);
3259 stream_putl (s, attr->local_pref);
3260 }
3261
3262 /* Atomic aggregate. */
3263 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))
3264 {
3265 stream_putc (s, BGP_ATTR_FLAG_TRANS);
3266 stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE);
3267 stream_putc (s, 0);
3268 }
3269
3270 /* Aggregator. */
3271 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR))
3272 {
3273 assert (attr->extra);
3274
3275 /* Common to BGP_ATTR_AGGREGATOR, regardless of ASN size */
3276 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3277 stream_putc (s, BGP_ATTR_AGGREGATOR);
3278
3279 if (use32bit)
3280 {
3281 /* AS4 capable peer */
3282 stream_putc (s, 8);
3283 stream_putl (s, attr->extra->aggregator_as);
3284 }
3285 else
3286 {
3287 /* 2-byte AS peer */
3288 stream_putc (s, 6);
3289
3290 /* Is ASN representable in 2-bytes? Or must AS_TRANS be used? */
3291 if ( attr->extra->aggregator_as > 65535 )
3292 {
3293 stream_putw (s, BGP_AS_TRANS);
3294
3295 /* we have to send AS4_AGGREGATOR, too.
3296 * we'll do that later in order to send attributes in ascending
3297 * order.
3298 */
3299 send_as4_aggregator = 1;
3300 }
3301 else
3302 stream_putw (s, (u_int16_t) attr->extra->aggregator_as);
3303 }
3304 stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
3305 }
3306
3307 /* Community attribute. */
3308 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
3309 && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES)))
3310 {
3311 if (attr->community->size * 4 > 255)
3312 {
3313 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3314 stream_putc (s, BGP_ATTR_COMMUNITIES);
3315 stream_putw (s, attr->community->size * 4);
3316 }
3317 else
3318 {
3319 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3320 stream_putc (s, BGP_ATTR_COMMUNITIES);
3321 stream_putc (s, attr->community->size * 4);
3322 }
3323 stream_put (s, attr->community->val, attr->community->size * 4);
3324 }
3325
3326 /*
3327 * Large Community attribute.
3328 */
3329 if (attr->extra &&
3330 CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY)
3331 && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES)))
3332 {
3333 if (attr->extra->lcommunity->size * 12 > 255)
3334 {
3335 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3336 stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
3337 stream_putw (s, attr->extra->lcommunity->size * 12);
3338 }
3339 else
3340 {
3341 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3342 stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
3343 stream_putc (s, attr->extra->lcommunity->size * 12);
3344 }
3345 stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12);
3346 }
3347
3348 /* Route Reflector. */
3349 if (peer->sort == BGP_PEER_IBGP
3350 && from
3351 && from->sort == BGP_PEER_IBGP)
3352 {
3353 /* Originator ID. */
3354 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
3355 stream_putc (s, BGP_ATTR_ORIGINATOR_ID);
3356 stream_putc (s, 4);
3357
3358 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
3359 stream_put_in_addr (s, &attr->extra->originator_id);
3360 else
3361 stream_put_in_addr (s, &from->remote_id);
3362
3363 /* Cluster list. */
3364 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
3365 stream_putc (s, BGP_ATTR_CLUSTER_LIST);
3366
3367 if (attr->extra && attr->extra->cluster)
3368 {
3369 stream_putc (s, attr->extra->cluster->length + 4);
3370 /* If this peer configuration's parent BGP has cluster_id. */
3371 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
3372 stream_put_in_addr (s, &bgp->cluster_id);
3373 else
3374 stream_put_in_addr (s, &bgp->router_id);
3375 stream_put (s, attr->extra->cluster->list,
3376 attr->extra->cluster->length);
3377 }
3378 else
3379 {
3380 stream_putc (s, 4);
3381 /* If this peer configuration's parent BGP has cluster_id. */
3382 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
3383 stream_put_in_addr (s, &bgp->cluster_id);
3384 else
3385 stream_put_in_addr (s, &bgp->router_id);
3386 }
3387 }
3388
3389 /* Extended Communities attribute. */
3390 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)
3391 && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES)))
3392 {
3393 struct attr_extra *attre = attr->extra;
3394
3395 assert (attre);
3396
3397 if (peer->sort == BGP_PEER_IBGP
3398 || peer->sort == BGP_PEER_CONFED)
3399 {
3400 if (attre->ecommunity->size * 8 > 255)
3401 {
3402 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3403 stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
3404 stream_putw (s, attre->ecommunity->size * 8);
3405 }
3406 else
3407 {
3408 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3409 stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
3410 stream_putc (s, attre->ecommunity->size * 8);
3411 }
3412 stream_put (s, attre->ecommunity->val, attre->ecommunity->size * 8);
3413 }
3414 else
3415 {
3416 u_int8_t *pnt;
3417 int tbit;
3418 int ecom_tr_size = 0;
3419 int i;
3420
3421 for (i = 0; i < attre->ecommunity->size; i++)
3422 {
3423 pnt = attre->ecommunity->val + (i * 8);
3424 tbit = *pnt;
3425
3426 if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))
3427 continue;
3428
3429 ecom_tr_size++;
3430 }
3431
3432 if (ecom_tr_size)
3433 {
3434 if (ecom_tr_size * 8 > 255)
3435 {
3436 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3437 stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
3438 stream_putw (s, ecom_tr_size * 8);
3439 }
3440 else
3441 {
3442 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3443 stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);
3444 stream_putc (s, ecom_tr_size * 8);
3445 }
3446
3447 for (i = 0; i < attre->ecommunity->size; i++)
3448 {
3449 pnt = attre->ecommunity->val + (i * 8);
3450 tbit = *pnt;
3451
3452 if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))
3453 continue;
3454
3455 stream_put (s, pnt, 8);
3456 }
3457 }
3458 }
3459 }
3460
3461 /* Label index attribute. */
3462 if (safi == SAFI_LABELED_UNICAST)
3463 {
3464 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
3465 {
3466 u_int32_t label_index;
3467
3468 assert (attr->extra);
3469 label_index = attr->extra->label_index;
3470
3471 if (label_index != BGP_INVALID_LABEL_INDEX)
3472 {
3473 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3474 stream_putc (s, BGP_ATTR_PREFIX_SID);
3475 stream_putc (s, 10);
3476 stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX);
3477 stream_putw (s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
3478 stream_putc (s, 0); // reserved
3479 stream_putw (s, 0); // flags
3480 stream_putl (s, label_index);
3481 }
3482 }
3483 }
3484
3485 if ( send_as4_path )
3486 {
3487 /* If the peer is NOT As4 capable, AND */
3488 /* there are ASnums > 65535 in path THEN
3489 * give out AS4_PATH */
3490
3491 /* Get rid of all AS_CONFED_SEQUENCE and AS_CONFED_SET
3492 * path segments!
3493 * Hm, I wonder... confederation things *should* only be at
3494 * the beginning of an aspath, right? Then we should use
3495 * aspath_delete_confed_seq for this, because it is already
3496 * there! (JK)
3497 * Folks, talk to me: what is reasonable here!?
3498 */
3499 aspath = aspath_delete_confed_seq (aspath);
3500
3501 stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
3502 stream_putc (s, BGP_ATTR_AS4_PATH);
3503 aspath_sizep = stream_get_endp (s);
3504 stream_putw (s, 0);
3505 stream_putw_at (s, aspath_sizep, aspath_put (s, aspath, 1));
3506 }
3507
3508 if (aspath != attr->aspath)
3509 aspath_free (aspath);
3510
3511 if ( send_as4_aggregator )
3512 {
3513 assert (attr->extra);
3514
3515 /* send AS4_AGGREGATOR, at this place */
3516 /* this section of code moved here in order to ensure the correct
3517 * *ascending* order of attributes
3518 */
3519 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3520 stream_putc (s, BGP_ATTR_AS4_AGGREGATOR);
3521 stream_putc (s, 8);
3522 stream_putl (s, attr->extra->aggregator_as);
3523 stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
3524 }
3525
3526 if (((afi == AFI_IP || afi == AFI_IP6) &&
3527 (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN)) ||
3528 (afi == AFI_L2VPN && safi == SAFI_EVPN))
3529 {
3530 /* Tunnel Encap attribute */
3531 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
3532
3533 #if ENABLE_BGP_VNC
3534 /* VNC attribute */
3535 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_VNC);
3536 #endif
3537 }
3538
3539 /* Unknown transit attribute. */
3540 if (attr->extra && attr->extra->transit)
3541 stream_put (s, attr->extra->transit->val, attr->extra->transit->length);
3542
3543 /* Return total size of attribute. */
3544 return stream_get_endp (s) - cp;
3545 }
3546
3547 size_t
3548 bgp_packet_mpunreach_start (struct stream *s, afi_t afi, safi_t safi)
3549 {
3550 unsigned long attrlen_pnt;
3551 iana_afi_t pkt_afi;
3552 safi_t pkt_safi;
3553
3554 /* Set extended bit always to encode the attribute length as 2 bytes */
3555 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN);
3556 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
3557
3558 attrlen_pnt = stream_get_endp (s);
3559 stream_putw (s, 0); /* Length of this attribute. */
3560
3561 /* Convert AFI, SAFI to values for packet. */
3562 bgp_map_afi_safi_int2iana (afi, safi, &pkt_afi, &pkt_safi);
3563
3564 stream_putw (s, pkt_afi);
3565 stream_putc (s, pkt_safi);
3566
3567 return attrlen_pnt;
3568 }
3569
3570 void
3571 bgp_packet_mpunreach_prefix (struct stream *s, struct prefix *p,
3572 afi_t afi, safi_t safi, struct prefix_rd *prd,
3573 u_char *tag, int addpath_encode,
3574 u_int32_t addpath_tx_id, struct attr *attr)
3575 {
3576 u_char wlabel[3] = {0x80, 0x00, 0x00};
3577
3578 if (safi == SAFI_LABELED_UNICAST)
3579 tag = wlabel;
3580
3581 return bgp_packet_mpattr_prefix (s, afi, safi, p, prd,
3582 tag, addpath_encode, addpath_tx_id, attr);
3583 }
3584
3585 void
3586 bgp_packet_mpunreach_end (struct stream *s, size_t attrlen_pnt)
3587 {
3588 bgp_packet_mpattr_end (s, attrlen_pnt);
3589 }
3590
3591 /* Initialization of attribute. */
3592 void
3593 bgp_attr_init (void)
3594 {
3595 aspath_init ();
3596 attrhash_init ();
3597 community_init ();
3598 ecommunity_init ();
3599 lcommunity_init ();
3600 cluster_init ();
3601 transit_init ();
3602 encap_init ();
3603 }
3604
3605 void
3606 bgp_attr_finish (void)
3607 {
3608 aspath_finish ();
3609 attrhash_finish ();
3610 community_finish ();
3611 ecommunity_finish ();
3612 lcommunity_finish ();
3613 cluster_finish ();
3614 transit_finish ();
3615 encap_finish ();
3616 }
3617
3618 /* Make attribute packet. */
3619 void
3620 bgp_dump_routes_attr (struct stream *s, struct attr *attr,
3621 struct prefix *prefix)
3622 {
3623 unsigned long cp;
3624 unsigned long len;
3625 size_t aspath_lenp;
3626 struct aspath *aspath;
3627 int addpath_encode = 0;
3628 u_int32_t addpath_tx_id = 0;
3629
3630 /* Remember current pointer. */
3631 cp = stream_get_endp (s);
3632
3633 /* Place holder of length. */
3634 stream_putw (s, 0);
3635
3636 /* Origin attribute. */
3637 stream_putc (s, BGP_ATTR_FLAG_TRANS);
3638 stream_putc (s, BGP_ATTR_ORIGIN);
3639 stream_putc (s, 1);
3640 stream_putc (s, attr->origin);
3641
3642 aspath = attr->aspath;
3643
3644 stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3645 stream_putc (s, BGP_ATTR_AS_PATH);
3646 aspath_lenp = stream_get_endp (s);
3647 stream_putw (s, 0);
3648
3649 stream_putw_at (s, aspath_lenp, aspath_put (s, aspath, 1));
3650
3651 /* Nexthop attribute. */
3652 /* If it's an IPv6 prefix, don't dump the IPv4 nexthop to save space */
3653 if(prefix != NULL && prefix->family != AF_INET6)
3654 {
3655 stream_putc (s, BGP_ATTR_FLAG_TRANS);
3656 stream_putc (s, BGP_ATTR_NEXT_HOP);
3657 stream_putc (s, 4);
3658 stream_put_ipv4 (s, attr->nexthop.s_addr);
3659 }
3660
3661 /* MED attribute. */
3662 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
3663 {
3664 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
3665 stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC);
3666 stream_putc (s, 4);
3667 stream_putl (s, attr->med);
3668 }
3669
3670 /* Local preference. */
3671 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
3672 {
3673 stream_putc (s, BGP_ATTR_FLAG_TRANS);
3674 stream_putc (s, BGP_ATTR_LOCAL_PREF);
3675 stream_putc (s, 4);
3676 stream_putl (s, attr->local_pref);
3677 }
3678
3679 /* Atomic aggregate. */
3680 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))
3681 {
3682 stream_putc (s, BGP_ATTR_FLAG_TRANS);
3683 stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE);
3684 stream_putc (s, 0);
3685 }
3686
3687 /* Aggregator. */
3688 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR))
3689 {
3690 assert (attr->extra);
3691 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3692 stream_putc (s, BGP_ATTR_AGGREGATOR);
3693 stream_putc (s, 8);
3694 stream_putl (s, attr->extra->aggregator_as);
3695 stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
3696 }
3697
3698 /* Community attribute. */
3699 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES))
3700 {
3701 if (attr->community->size * 4 > 255)
3702 {
3703 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3704 stream_putc (s, BGP_ATTR_COMMUNITIES);
3705 stream_putw (s, attr->community->size * 4);
3706 }
3707 else
3708 {
3709 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3710 stream_putc (s, BGP_ATTR_COMMUNITIES);
3711 stream_putc (s, attr->community->size * 4);
3712 }
3713 stream_put (s, attr->community->val, attr->community->size * 4);
3714 }
3715
3716 /* Large Community attribute. */
3717 if (attr->extra && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES))
3718 {
3719 if (attr->extra->lcommunity->size * 12 > 255)
3720 {
3721 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);
3722 stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
3723 stream_putw (s, attr->extra->lcommunity->size * 12);
3724 }
3725 else
3726 {
3727 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3728 stream_putc (s, BGP_ATTR_LARGE_COMMUNITIES);
3729 stream_putc (s, attr->extra->lcommunity->size * 12);
3730 }
3731
3732 stream_put (s, attr->extra->lcommunity->val, attr->extra->lcommunity->size * 12);
3733 }
3734
3735 /* Add a MP_NLRI attribute to dump the IPv6 next hop */
3736 if (prefix != NULL && prefix->family == AF_INET6 && attr->extra &&
3737 (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL ||
3738 attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) )
3739 {
3740 int sizep;
3741 struct attr_extra *attre = attr->extra;
3742
3743 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
3744 stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
3745 sizep = stream_get_endp (s);
3746
3747 /* MP header */
3748 stream_putc (s, 0); /* Marker: Attribute length. */
3749 stream_putw(s, AFI_IP6); /* AFI */
3750 stream_putc(s, SAFI_UNICAST); /* SAFI */
3751
3752 /* Next hop */
3753 stream_putc(s, attre->mp_nexthop_len);
3754 stream_put(s, &attre->mp_nexthop_global, IPV6_MAX_BYTELEN);
3755 if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
3756 stream_put(s, &attre->mp_nexthop_local, IPV6_MAX_BYTELEN);
3757
3758 /* SNPA */
3759 stream_putc(s, 0);
3760
3761 /* Prefix */
3762 stream_put_prefix_addpath (s, prefix, addpath_encode, addpath_tx_id);
3763
3764 /* Set MP attribute length. */
3765 stream_putc_at (s, sizep, (stream_get_endp (s) - sizep) - 1);
3766 }
3767
3768 /* Prefix SID */
3769 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID))
3770 {
3771 assert (attr->extra);
3772
3773 if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
3774 {
3775 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);
3776 stream_putc (s, BGP_ATTR_PREFIX_SID);
3777 stream_putc (s, 10);
3778 stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX);
3779 stream_putc (s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
3780 stream_putc (s, 0); // reserved
3781 stream_putw (s, 0); // flags
3782 stream_putl (s, attr->extra->label_index);
3783 }
3784 }
3785
3786 /* Return total size of attribute. */
3787 len = stream_get_endp (s) - cp - 2;
3788 stream_putw_at (s, cp, len);
3789 }