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