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