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