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